예제 #1
0
 def _anf_from_poly(self, polynomial):
     #build tap set fn from polynomial
     newFn = [[[i + 1]] for i in range(self.size - 1)] + [[]]
     for i in range(self.size):
         if polynomial[i + 1]:
             newFn[i] += [[0]]
     self.anf = [ANF(bitFn) for bitFn in newFn]
예제 #2
0
    def __init__(self, size, nonlinear=True, permute=False):
        self.anf = [[[i], list(range(i))] for i in range(size)]
        self.anf[0][1] = True
        self.size = size
        self.induction_order = list(range(self.size))

        if nonlinear: self.GenerateNonlinearity()
        if permute:
            shuffle(self.induction_order)
            newAnf = []
            for bitFn in self.anf:
                newFn = []
                for term in bitFn:
                    if type(term) == bool:
                        newFn.append(term)
                    else:
                        newTerm = []
                        for var in term:
                            newTerm.append(self.induction_order[var])
                        newFn.append(newTerm)
                newAnf.append(newFn)
            for i in range(self.size):
                self.anf[self.induction_order[i]] = newAnf[i]

        #convert to ANF objects:
        self.anf = [ANF(bitFn) for bitFn in self.anf]
예제 #3
0
    def shiftTerms(self, terms, idxA, idxB):
        for term in terms:
            valid = True
            for var in term:
                valid &= (var >= (idxA - idxB))
            if not valid:
                raise ValueError("Invalid shift attempted for term: " +
                                 str(term))

            newTerm = frozenset([(i - idxA + idxB) for i in term])

            self.anf[idxA].remove(term)
            self.anf[idxB] += ANF([newTerm])
예제 #4
0
    def _anf_from_poly(self, size, primitive_polynomial):
        #Create the top function:
        # Example: [1,0,1,1] -> [0,2,3] -> [[3],[1],[0]]
        topFn = [[size - idx] for (idx, t) in enumerate(primitive_polynomial)
                 if t == 1]
        # Example: [[3],[1],[0]] -> [[0],[1],[3]]
        topFn = topFn[::-1]
        # Example: [[0],[1],[3]] -> [[[0],[1]]]
        topFn = [topFn[:-1]]

        #create the shift for all other bits
        shiftFn = [[[i + 1]] for i in range(size - 1)]

        return [ANF(bitFn) for bitFn in (shiftFn + topFn)]
예제 #5
0
    def __init__(self, size, primitive_poly, \
                 nonlinear = True, maxAnds = 4, tapDensity = .75):
        #convert koopman string into polynomial:
        if type(primitive_poly) == str:
            primitive_poly = list(
                BitVector(intVal=int(primitive_poly, 16), size=size)) + [1]
        self.primitive_polynomial = primitive_poly

        #same as fibonacci ANF generation:
        top_fn = [[size - idx] for (idx, t) in enumerate(primitive_poly)
                  if t == 1][::-1][:-1]
        self.anf = [[[(i + 1) % size]] for i in range(size - 1)] + [top_fn]
        self.anf = [ANF(bitFn) for bitFn in self.anf]

        self.size = size
        self.tau = self.size - 1

        if nonlinear: self.generateNonlinearity(maxAnds, tapDensity)
예제 #6
0
    def addNonLinearTerm(self, maxAnds):
        minDest = maxDest = 0
        while not (minDest < maxDest):
            numTaps = randint(2, maxAnds)
            newTerm = frozenset(sample(range(1, self.size), numTaps))
            maxDest = self.getMaxDestination(newTerm)
            minDest = self.getMinDestination(newTerm)

        idx1, idx2 = sample(range(minDest, maxDest + 1), 2)

        #add first copy
        self.anf[self.size - 1].add(newTerm)
        self.shiftTerms([newTerm], self.size - 1, idx1)

        #add second copy
        self.anf[self.size - 1].add(newTerm)
        self.shiftTerms([newTerm], self.size - 1, idx2)

        #fix edge case caused by set merging
        if idx1 == self.size - 1:
            self.anf[self.size - 1] += ANF([newTerm])
예제 #7
0
 def _inverted_from_poly(self, polynomial):
     newFn = [[]] + [[[i - 1]] for i in range(1, self.size)]
     for i in range(self.size):
         if polynomial[i]:
             newFn[i] += [[self.size - 1]]
     self.anf = [ANF(bitFn) for bitFn in newFn]