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_gate(ultimate_level, fanin_frac, gate_name, gate_factory):
    """Creates a random family 1 or 2 gate using gate_factory.

    Args:
        ultimate_level: a list of gates or wires at the level directly above
            the one to which the new gate will belong.
        fanin_frac: the fraction of the gates at the ultimate_level which will
            serve as input to the new gate.
        gate_name: the name which the new gate will have.
        gate_factory: the method used to generate the new gate.
    """
    if fanin_frac == 1:
        fanin = len(ultimate_level)
        inputs = ultimate_level
    else:
        max_fanin = len(ultimate_level)
        # compute the standard deviation sigma as per the test plan appendix:
        sigma = min(max_fanin * (1 - fanin_frac), max_fanin * fanin_frac) / 3
        # compute the fanin as a normal distribution with mean max_fanin times
        # fanin frac, and standard deviation above:
        fanin = max(2, min(int(round(sr.gauss(max_fanin * fanin_frac, sigma))),
                       max_fanin))
        # choose random inputs:
        inputs = sr.sample(ultimate_level, fanin)
    # choose the negations:
    negations = [int(sr.getrandbits(1)) for neg_ind in xrange(fanin)]
    return gate_factory(gate_name, inputs, negations)
 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)
Exemple #5
0
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 generate(self):
     """Populates the circuit, input and output files with a circuit, an
     input, and the corresponding output with the appropriate parameters."""
     # create the header and write it to the circuit file:
     header_string = self._create_circuit_header()
     # create the input wires and write the inputs to the input file:
     input_wires = self._create_input_wires()
     # set set of all circuit objects already created:
     levels = [input_wires]
     # initialize the global gate counter, which acts as the unique numerical
     # id of each gate:
     unique_gate_num_gen = itertools.count()
     # for each level:
     for level_index in xrange(self._D):
         # Create the list of gates at this level:
         this_level = [None] * self._W
         for gate_ind in xrange(self._W):
             displayname = "".join(["G",str(unique_gate_num_gen.next())])
             # make the new gate:
             new_gate = self._gate_maker(levels, displayname)
             new_gate_output = int(sr.getrandbits(1))
             new_gate.balance(new_gate_output)
             # add this gate to our list of gates at this level:
             this_level[gate_ind] = new_gate
         # set things up for the next level:
         ultimate_level = this_level
         levels.append(this_level)
     output_gate = sr.choice(levels[-1])
     output_gate.set_name("output_gate")
     # choose a random output, and write it to the output file:
     output = int(sr.getrandbits(1))
     self._output_file.write(str(output))
     # balance the output gate with respect to the chosen output:
     output_gate.balance(output)
     circ = sc.StealthCircuit(input_wires, output_gate)
     # write the circuit to the circuit file:
     self._circuit_file.write(circ.display())
Exemple #7
0
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)
Exemple #8
0
def make_random_input(L, W):
    """Creates a random input with W batches, each with L bits."""
    return ci.Input([ib.IBMBatch([int(sr.getrandbits(1))
                                  for inp_num in xrange(L)])
                     for batch_num in xrange(W)])
Exemple #9
0
 def _randomize_negations(self):
     """Replaces the existing negations with new randomly chosen ones.
     Recomputes the stored value, since the negations were changed."""
     self.__negations = [bool(sr.getrandbits(1))
                         for bal_ind in xrange(len(self.get_inputs()))]
     self.__value = None
 def generate(self):
     """Populates the circuit, input and output files with a circuit, an
     input, and the corresponding output with the appropriate parameters."""
     # create the header and write it to the circuit file:
     header_string = self._create_circuit_header()
     # create the input wires and write the inputs to the input file:
     input_wires = self._create_input_wires()
     # create the output and write it to the output file:
     output = self._create_output()
     # initialize the global gate counter, which acts as the unique numerical
     # id of each gate:
     unique_gate_num_gen = itertools.count(self._W, 1)
     # set the 'ultimate level' for the first level of gates:
     ultimate_level = input_wires
     # for each level:
     for level_ind in xrange(len(self._level_type_array)):
         if not self._trimming:
             # if this circuit is not being trimmed, then we have to write
             # 'L' to the circuit file, because we will not be creating a
             # circuit object to take care of our printing for us:
             self._circuit_file.write("\nL")
         # if this is an intermediate level:
         if self._level_type_array[level_ind] == LEVEL_TYPES.RANDOM:
             num_gates = self._G
             fanin_frac = self._fg
             make_gate = self._gate_maker
         # if this is an XOR level:
         elif self._level_type_array[level_ind] == LEVEL_TYPES.XOR:
             num_gates = self._X
             fanin_frac = self._fx
             make_gate = TYPE_TO_GATE_GEN[GATE_TYPES.XOR]
         # Create the list of gates at this level:
         this_level = [None] * num_gates
         for gate_ind in xrange(num_gates):
             displayname = "".join(["G", str(unique_gate_num_gen.next())])
             # make the random gate:
             new_gate = make_gate(ultimate_level, fanin_frac, displayname)
             # choose a random output, and balance the new gate with respect
             # to that output:
             new_gate_output = int(sr.getrandbits(1))
             new_gate.balance(new_gate_output)
             if not self._trimming:
                 # if this circuit is not being trimmed, then we can just
                 # write the gate to the circuit file right away:
                 self._circuit_file.write(
                     "".join(["\n", new_gate.get_full_display_string()]))
                 # since this gate is already written to the circuit file,
                 # we can save on memory space by re-representing it as an
                 # input wire with the correct value:
                 new_gate = sw.StealthInputWire(displayname, new_gate_output)
             # add this gate to our list of gates at this level:
             this_level[gate_ind] = new_gate
             # increment the global gate counter:
         # set things up for the next level:
         ultimate_level = this_level
     # create the output gate:
     negations = [int(sr.getrandbits(1))
                  for neg_ind in xrange(len(ultimate_level))]
     output_gate = self._gate_maker(ultimate_level, 1, "output_gate")
     # balance the output gate with respect to the chosen output:
     output_gate.balance(output)
     if self._trimming:
         # if this circuit is being trimmed, then we create a circuit and
         # write it to the circuit_file:
         circ = sc.StealthCircuit(input_wires, output_gate)
         self._circuit_file.write(circ.display())
     else:
         # otherwise, we will have already written all the gates as we went
         # along, so we only need to record the output gate:
         self._circuit_file.write("".join(["\nL\n",
                                     output_gate.get_full_display_string()]))
 def _create_output(self):
     """returns the output, and writes the output to the output file"""
     # choose a random output, and write it to the output file:
     output = int(sr.getrandbits(1))
     self._output_file.write(str(output))
     return output
def make_random_input(W):
    """Returns an array of W random bits."""
    # TODO: this can probably be made to run faster by generating all W random
    # bits at once.
    return si.Input([int(sr.getrandbits(1)) for inp_num in xrange(W)])
def make_random_input_wire(displayname):
    """Makes a random input wire with the displayname. Its value is set to True
    with probability .5, and to False with probability .5."""
    val = int(sr.getrandbits(1))
    return sw.StealthInputWire(displayname, val)