#!/usr/bin/env python
## -*- coding: utf-8 -*-
##
## This program is under the terms of the BSD License.
## Jonathan Salwan - 2020-03-18
##
## Generate oracles table for obfuscated expressions synthesis
##
import sys
import operator
from ctypes import c_uint8, c_uint16, c_uint32, c_uint64
from random import randrange
HOW_BIG_IS_THE_TABLE = 15
def unary_none(x):
return x
unary_operators = [
[unary_none, ''], # None
[operator.__neg__, '-'], # Negative
[operator.__inv__, '~'] # Bitwise NOT
]
binary_operators = [
[operator.__add__, '+'], # Add
[operator.__sub__, '-'], # Substract
[operator.__xor__, '^'], # Bitwise XOR
[operator.__or__, '|'], # Bitwise OR
[operator.__and__, '&'], # Bitwise AND
[operator.__mul__, '*'], # Multiply
]
def gen_binary_operator(main_unary_op, main_unary_sign, binary_op, binary_sign, unary_op_a=unary_none, unary_sign_a='', unary_op_b=unary_none, unary_sign_b=''):
print(' {')
print(' # 8-bit, 16-bit, 32-bit and 64-bit oracles')
print(' # Items representation: (vars size, a, b, result)')
print(' \'oracles\' : [')
for i in range(HOW_BIG_IS_THE_TABLE):
s1 = c_uint8(randrange(1, 0x100))
s2 = c_uint8(randrange(1, 0x100))
r1 = c_uint8(main_unary_op(binary_op(unary_op_a(s1.value), unary_op_b(s2.value))))
s3 = c_uint16(randrange(0x100, 0x10000))
s4 = c_uint16(randrange(0x100, 0x10000))
r2 = c_uint16(main_unary_op(binary_op(unary_op_a(s3.value), unary_op_b(s4.value))))
s5 = c_uint32(randrange(0x10000, 0x100000000))
s6 = c_uint32(randrange(0x10000, 0x100000000))
r3 = c_uint32(main_unary_op(binary_op(unary_op_a(s5.value), unary_op_b(s6.value))))
s7 = c_uint64(randrange(0x100000000, 0x10000000000000000))
s8 = c_uint64(randrange(0x100000000, 0x10000000000000000))
r4 = c_uint64(main_unary_op(binary_op(unary_op_a(s7.value), unary_op_b(s8.value))))
print(' (8, %d, %d, %d), (16, %d, %d, %d), (32, %d, %d, %d), (64, %d, %d, %d),'
% (s1.value, s2.value, r1.value, s3.value, s4.value, r2.value, s5.value, s6.value, r3.value, s7.value, s8.value, r4.value)
)
print(' ],')
print(' \'synthesis\' : \'%s(%sa %s %sb)\'' %(main_unary_sign, unary_sign_a, binary_sign, unary_sign_b))
print(' },')
return
def main():
print('oracles_table = [')
for main_un_op, main_un_sign in unary_operators:
for bi_op, bi_sign in binary_operators:
gen_binary_operator(main_un_op, main_un_sign, binary_op=bi_op, binary_sign=bi_sign)
gen_binary_operator(main_un_op, main_un_sign, binary_op=bi_op, binary_sign=bi_sign, unary_op_a=operator.__neg__, unary_sign_a='-')
gen_binary_operator(main_un_op, main_un_sign, binary_op=bi_op, binary_sign=bi_sign, unary_op_a=operator.__inv__, unary_sign_a='~')
gen_binary_operator(main_un_op, main_un_sign, binary_op=bi_op, binary_sign=bi_sign, unary_op_b=operator.__neg__, unary_sign_b='-')
gen_binary_operator(main_un_op, main_un_sign, binary_op=bi_op, binary_sign=bi_sign, unary_op_b=operator.__inv__, unary_sign_b='~')
gen_binary_operator(main_un_op, main_un_sign, binary_op=bi_op, binary_sign=bi_sign, unary_op_a=operator.__neg__, unary_sign_a='-', unary_op_b=operator.__neg__, unary_sign_b='-')
gen_binary_operator(main_un_op, main_un_sign, binary_op=bi_op, binary_sign=bi_sign, unary_op_a=operator.__inv__, unary_sign_a='~', unary_op_b=operator.__neg__, unary_sign_b='-')
gen_binary_operator(main_un_op, main_un_sign, binary_op=bi_op, binary_sign=bi_sign, unary_op_a=operator.__neg__, unary_sign_a='-', unary_op_b=operator.__inv__, unary_sign_b='~')
gen_binary_operator(main_un_op, main_un_sign, binary_op=bi_op, binary_sign=bi_sign, unary_op_a=operator.__inv__, unary_sign_a='~', unary_op_b=operator.__inv__, unary_sign_b='~')
print(']')
return 0
if __name__ == '__main__':
sys.exit(main())