def make_random_fam_3_gate(levels, gate_name, gate_factory): """Creates a random family 3 gate using gate_factory. A family 3 gate takes in two inputs, at least one of which is from the level directly above it. Args: levels: a list of lists of gates, one corresponding to each level already created in the circuit. gate_name: the name which the new gate will have. gate_factory: the method used to generate the new gate. """ W = len(levels[0]) assert(all(len(level) == W for level in levels)) # make sure that we have at least two possible inputs: assert(W * len(levels) > 1) # find the first input among the circuit objects in the ultimate level: input1_index = sr.randint(0, W - 1) input1 = levels[-1][input1_index] # find the second input among all available circuit objects: input2_index = sr.randint(0, (len(levels) * W) - 1) while input2_index == input1_index: input2_index = sr.randint(0, (len(levels) * W) - 1) input2_inp_index = input2_index % W input2_level_index = len(levels) - ((input2_index - input2_inp_index) / W) - 1 input2_inp_index = input2_index % W input2 = levels[input2_level_index][input2_inp_index] # create the gate: inputs = [input1, input2] negations = [int(sr.getrandbits(1)) for neg_ind in xrange(2)] return gate_factory(gate_name, inputs, negations)
def make_random_one_inp_and_const_int_gate(L, ultimate_level, penultimate_level, gate_name, circuit, gate_factory): """creates a random gate with one input and a constant that is an integer. """ # This gate requires one input; at least one input should be available. assert(len(ultimate_level) + len(penultimate_level) > 0) input1_index = sr.randint(0, len(ultimate_level) - 1) input1 = ultimate_level[input1_index] const = sr.randint(0, L - 1) return gate_factory(gate_name, input1, const, circuit)
def make_random_one_inp_and_const_inp_gate(B, L, ultimate_level, penultimate_level, gate_name, circuit, gate_factory): """creates a random gate with one input and a constant that is an input batch.""" # This gate requires one input; at least one input should be available. assert (len(ultimate_level) + len(penultimate_level) > 0) input1_index = sr.randint(0, len(ultimate_level) - 1) input1 = ultimate_level[input1_index] const = ci.Input( [ib.IBMBatch([int(sr.randint(0, B)) for inp_ind in xrange(L)])]) return gate_factory(gate_name, input1, const, circuit)
def make_random_two_inp_gate(L, ultimate_level, penultimate_level, gate_name, circuit, gate_factory): """creates a random gate with two inputs.""" # This gate requires two inputs; at least two inputs should be available. assert(len(ultimate_level) + len(penultimate_level) > 1) input1_index = sr.randint(0, len(ultimate_level) - 1) input1 = ultimate_level[input1_index] input2_index = sr.randint(0, len(ultimate_level) + len(penultimate_level) - 1) while input2_index == input1_index: input2_index = sr.randint(0, len(ultimate_level) + len(penultimate_level) - 1) if input2_index < len(ultimate_level): input2 = ultimate_level[input2_index] else: input2 = penultimate_level[input2_index - len(ultimate_level)] return gate_factory(gate_name, input1, input2, circuit)
def make_random_one_inp_and_const_inp_gate(L, ultimate_level, penultimate_level, gate_name, circuit, gate_factory): """creates a random gate with one input and a constant that is an input batch.""" # This gate requires one input; at least one input should be available. assert(len(ultimate_level) + len(penultimate_level) > 0) input1_index = sr.randint(0, len(ultimate_level) - 1) input1 = ultimate_level[input1_index] const = ci.Input([ib.IBMBatch([int(sr.getrandbits(1)) for inp_ind in xrange(L)])]) return gate_factory(gate_name, input1, const, circuit)
def make_random_two_inp_and_const_inp_gate(L, ultimate_level, penultimate_level, gate_name, circuit, gate_factory): """creats a random gate with two inputs and a constant that is an input batch.""" # This gate requires two inputs; at least two inputs should be available. assert(len(ultimate_level) + len(penultimate_level) > 1) input1_index = sr.randint(0, len(ultimate_level) - 1) input1 = ultimate_level[input1_index] input2_index = sr.randint(0, len(ultimate_level) + len(penultimate_level) - 1) while input2_index == input1_index: input2_index = sr.randint(0, len(ultimate_level) + len(penultimate_level) - 1) if input2_index < len(ultimate_level): input2 = ultimate_level[input2_index] else: input2 = penultimate_level[input2_index - len(ultimate_level)] const = ci.Input([ib.IBMBatch([int(sr.getrandbits(1)) for inp_ind in xrange(L)])]) return gate_factory(gate_name, input1, input2, const, circuit)
def balance(self, desired_output): """Changes the negations on the inputs of this gate so that the gate yeilds the bit desired_output.""" assert (desired_output == True or desired_output == False) current_eval = self.evaluate() # if the gate does not currently evaluate to the desired_output, tweak # the negations in such a way as to force it to evaluate to the # desired_output. This can be done by flipping a single negation: inp_ind = sr.randint(0, self.get_num_inputs() - 1) self._negate(inp_ind) self._set_value(desired_output)
def test_balancing_randomized(self): """ Test to determine that balancing forces the desired output. Tests many randomized cases. """ num_tests = 100 min_num_inputs = 2 max_num_inputs = 20 for test_num in xrange(num_tests): num_inputs = sr.randint(min_num_inputs, max_num_inputs) inputs = [sw.StealthInputWire("wire", bool(sr.getrandbits(1))) for input_num in xrange(num_inputs)] negations = [bool(sr.getrandbits(1)) for input_num in xrange(num_inputs)] gate = sgx.StealthXorGate("xor_gate", inputs, negations) desired_output = bool(sr.getrandbits(1)) gate.balance(desired_output) self.assertEqual(gate.evaluate(), desired_output)
def test_balancing_randomized(self): """ Test to determine that balancing forces the desired output. Tests many randomized cases. """ num_tests = 100 min_num_inputs = 2 max_num_inputs = 20 for test_num in xrange(num_tests): num_inputs = sr.randint(min_num_inputs, max_num_inputs) inputs = [sw.StealthInputWire("wire", bool(sr.getrandbits(1))) for input_num in xrange(num_inputs)] negations = [bool(sr.getrandbits(1)) for input_num in xrange(num_inputs)] gate = sga.StealthAndGate("and_gate", inputs, negations) desired_output = bool(sr.getrandbits(1)) gate.balance(desired_output) self.assertEqual(gate.evaluate(), desired_output)
def balance(self, desired_output): """Changes the negations on the inputs of this gate so that the gate yeilds the bit desired_output.""" assert (desired_output == True or desired_output == False) current_eval = self.evaluate() # if the gate does not currently evaluate to the desired_output, tweak # the negations in such a way as to force it to evaluate to the # desired_output: if current_eval != desired_output: if (desired_output == True): # if the gate does not currently evaluate to True, we can get it # to do so by flipping a single negation: inp_ind = sr.randint(0, self.get_num_inputs() - 1) self._negate(inp_ind) else: # Getting an OR to evaluate to False is harder; we must make # sure that every input evaluates to False. for bal_ind2 in xrange(self.get_num_inputs()): if self._get_value_with_negation(bal_ind2) == True: self._negate(bal_ind2) self._set_value(desired_output)
def balance(self, desired_output): """Changes the negations on the inputs of this gate so that the gate yeilds the bit desired_output.""" assert(desired_output == True or desired_output == False) current_eval = self.evaluate() # if the gate does not currently evaluate to the desired_output, tweak # the negations in such a way as to force it to evaluate to the # desired_output: if current_eval != desired_output: if (desired_output == True): # if the gate does not currently evaluate to True, we can get it # to do so by flipping a single negation: inp_ind = sr.randint(0, self.get_num_inputs() - 1) self._negate(inp_ind) else: # Getting an OR to evaluate to False is harder; we must make # sure that every input evaluates to False. for bal_ind2 in xrange(self.get_num_inputs()): if self._get_value_with_negation(bal_ind2) == True: self._negate(bal_ind2) self._set_value(desired_output)
def make_random_input(L, W, B): """Creates a random input with W batches, each with L bits.""" return ci.Input([ ib.IBMBatch([int(sr.randint(0, B)) for inp_num in xrange(L)]) for batch_num in xrange(W) ])
def make_uniform_random_fam3_gate(levels, gate_name): """Makes a random family 3 gate with type determined at random. """ gate_type = sr.randint(0, GATE_TYPES.size() - 1) gate_factory = TYPE_TO_FAM3_GATE_GEN[gate_type] return gate_factory(levels, gate_name)
def make_uniform_random_gate(ultimate_level, fanin_frac, gate_name): """Makes a random family 1 or 2 gate with type determined at random. """ gate_type = sr.randint(0, GATE_TYPES.size() - 1) gate_factory = TYPE_TO_GATE_GEN[gate_type] return gate_factory(ultimate_level, fanin_frac, gate_name)