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.randbit()) for bal_ind in xrange(len(self.get_inputs())) ] self.__value = None
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 = [sr.randbit() for neg_ind in xrange(fanin)] return gate_factory(gate_name, inputs, negations)
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 = [sr.randbit() for neg_ind in xrange(2)] return gate_factory(gate_name, inputs, negations)
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([sr.randbit() for inp_ind in xrange(L)])]) return gate_factory(gate_name, input1, const, circuit)
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.randbit())) for input_num in xrange(num_inputs) ] negations = [ bool(sr.randbit()) for input_num in xrange(num_inputs) ] gate = sgo.StealthOrGate("or_gate", inputs, negations) desired_output = bool(sr.randbit()) gate.balance(desired_output) self.assertEqual(gate.evaluate(), desired_output)
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 = sr.randbit() 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 = sr.randbit() 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())
def generate(self, *args): # Get the bit-length bit_length = spar_random.randint(0, 64) # Now, skep it a bit toward shorter numbers if bit_length == 64: if spar_random.randint(1, 5000) != 1: bit_length = spar_random.randint(0, 63) # Generate a random int of that bit-length if bit_length == 0: return 0 else: return_me = 1 random_bits = bit_length - 1 for _ in xrange(random_bits): return_me *= 2 return_me += spar_random.randbit() return return_me
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([sr.randbit() for inp_ind in xrange(L)])]) return gate_factory(gate_name, input1, input2, const, circuit)
def generate_two_sided(self, record_set_size, range_size, db_size): '''Returns a tuple containing a the lower and upper values of a randomly generated range''' #Get the desired density by dividing by the range of the bucket desired_density = record_set_size / range_size #Find all bit lengths that have that density density = self.__bucket_density(db_size) close_enoughs = [] min_bit_length = range_size.bit_length() + 1 for bit_len in xrange(min_bit_length, 65): if self.__close_enough(density[bit_len], desired_density): close_enoughs.append(bit_len) if len(close_enoughs) == 0: raise FooInputs elif len(close_enoughs) == 1: bit_length = close_enoughs[0] else: bit_length = spar_random.choice(close_enoughs) #Generate a random range of bit length range_size range = 1 for _ in xrange(range_size.bit_length() - 1): range *= 2 range += spar_random.randbit() assert range.bit_length() == range_size.bit_length() #generate random starting point within the bucket for the range, #the lower value is generated randomly and then multiplied by 2 #because randint cannot compute values larger than 2**63 lower_half = spar_random.randint(2**(bit_length - 1) / 2, (2**(bit_length) - range_size) / 2) lower = lower_half * 2 upper = lower + range return (lower, upper)
def make_random_input(L, W): """Creates a random input with W batches, each with L bits.""" return ci.Input([ ib.IBMBatch([sr.randbit() for inp_num in xrange(L)]) for batch_num in xrange(W) ])
def generate(self): return spar_random.randbit()
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 = sr.randbit() 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 = [sr.randbit() 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 = sr.randbit() 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([sr.randbit() 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 = sr.randbit() return sw.StealthInputWire(displayname, val)