예제 #1
0
 def _small_irriducible(char, degree):
     """
     Return an irreducible polynomial of self.degree with a small
     number of non-zero coefficients.
     """
     cardinality = char**degree
     basefield = FinitePrimeField.getInstance(char)
     top = uniutil.polynomial({degree: 1}, coeffring=basefield)
     for seed in range(degree - 1):
         for const in range(1, char):
             coeffs = [const] + arith1.expand(seed, 2)
             cand = uniutil.polynomial(enumerate(coeffs),
                                       coeffring=basefield) + top
             if cand.isirreducible():
                 _log.debug(cand.order.format(cand))
                 return cand
     for subdeg in range(degree):
         subseedbound = char**subdeg
         for subseed in range(subseedbound + 1, char * subseedbound):
             if not subseed % char:
                 continue
             seed = subseed + cardinality
             cand = uniutil.polynomial(enumerate(
                 arith1.expand(seed, cardinality)),
                                       coeffring=basefield)
             if cand.isirreducible():
                 return cand
예제 #2
0
 def _random_irriducible(char, degree):
     """
     Return randomly chosen irreducible polynomial of self.degree.
     """
     cardinality = char ** degree
     basefield = FinitePrimeField.getInstance(char)
     seed = bigrandom.randrange(1, char) + cardinality
     cand = uniutil.FiniteFieldPolynomial(enumerate(arith1.expand(seed, cardinality)), coeffring=basefield)
     while cand.degree() < degree or not cand.isirreducible():
         seed = bigrandom.randrange(1, cardinality) + cardinality
         cand = uniutil.FiniteFieldPolynomial(enumerate(arith1.expand(seed, cardinality)), coeffring=basefield)
     _log.debug(cand.order.format(cand))
     return cand
예제 #3
0
파일: ecm.py 프로젝트: nickspoon/part-ii
def mul(Q, x, C, n):
    """
    Return x*Q on the curve C mod n.

    m*Q and (m+1)*Q are being tracked in the main loop.
    """
    if x == 0:
        return POINT_AT_INFINITY
    if x == 1:
        return Q
    if x == 2:
        return double(Q, C, n)
    minor = Q
    major = double(Q, C, n)
    binary = _arith1.expand(x, 2)
    lastbit, binary = binary[0], binary[1:]
    while binary:
        if binary.pop() == 1:
            minor = add(major, minor, Q, n)
            major = double(major, C, n)
        else:
            major = add(minor, major, Q, n)
            minor = double(minor, C, n)
    if lastbit:
        return add(minor, major, Q, n)
    return double(minor, C, n)
예제 #4
0
def mul(Q, x, C, n):
    """
    Return x*Q on the curve C mod n.

    m*Q and (m+1)*Q are being tracked in the main loop.
    """
    if x == 0:
        return POINT_AT_INFINITY
    if x == 1:
        return Q
    if x == 2:
        return double(Q, C, n)
    minor = Q
    major = double(Q, C, n)
    binary = _arith1.expand(x, 2)
    lastbit, binary = binary[0], binary[1:]
    while binary:
        if binary.pop() == 1:
            minor = add(major, minor, Q, n)
            major = double(major, C, n)
        else:
            major = add(minor, major, Q, n)
            minor = double(minor, C, n)
    if lastbit:
        return add(minor, major, Q, n)
    return double(minor, C, n)
예제 #5
0
 def createElement(self, seed):
     """
     Create an element of the field.
     """
     if isinstance(seed, int):
         expansion = arith1.expand(seed, self.char)
         return FiniteExtendedFieldElement(
             FinitePrimeFieldPolynomial(enumerate(expansion),
                                        self.basefield), self)
     elif isinstance(seed, FinitePrimeFieldPolynomial):
         return FiniteExtendedFieldElement(seed, self)
     elif isinstance(seed, FinitePrimeFieldElement
                     ) and seed.m == self.getCharacteristic():
         return FiniteExtendedFieldElement(
             FinitePrimeFieldPolynomial([(0, seed)], self.basefield), self)
     elif seed in self:
         # seed is in self, return only embedding
         return self.zero + seed
     else:
         try:
             # lastly check sequence
             return FiniteExtendedFieldElement(
                 FinitePrimeFieldPolynomial(enumerate(seed),
                                            self.basefield), self)
         except TypeError:
             raise TypeError("seed %s is not an appropriate object." %
                             str(seed))
예제 #6
0
 def createElement(self, seed):
     """
     Create an element of the field.
     """
     if isinstance(seed, int):
         expansion = arith1.expand(seed, card(self.basefield))
         return ExtendedFieldElement(
             uniutil.FiniteFieldPolynomial(enumerate(expansion),
                                           self.basefield), self)
     elif seed in self.basefield:
         return ExtendedFieldElement(
             uniutil.FiniteFieldPolynomial([(0, seed)], self.basefield),
             self)
     elif seed in self:
         # seed is in self, return only embedding
         return self.zero + seed
     elif (isinstance(seed, uniutil.FiniteFieldPolynomial)
           and seed.getCoefficientRing() is self.basefield):
         return ExtendedFieldElement(seed, self)
     else:
         try:
             # lastly check sequence
             return ExtendedFieldElement(
                 uniutil.FiniteFieldPolynomial(enumerate(seed),
                                               self.basefield), self)
         except TypeError:
             raise TypeError("seed %s is not an appropriate object." %
                             str(seed))
예제 #7
0
 def createElement(self, seed):
     """
     Create an element of the field.
     """
     if isinstance(seed, (int, long)):
         expansion = arith1.expand(seed, card(self.basefield))
         return ExtendedFieldElement(
             uniutil.FiniteFieldPolynomial(enumerate(expansion), self.basefield),
             self)
     elif seed in self.basefield:
         return ExtendedFieldElement(
             uniutil.FiniteFieldPolynomial([(0, seed)], self.basefield),
             self)
     elif seed in self:
         # seed is in self, return only embedding
         return self.zero + seed
     elif (isinstance(seed, uniutil.FiniteFieldPolynomial) and
           seed.getCoefficientRing() is self.basefield):
         return ExtendedFieldElement(seed, self)
     else:
         try:
             # lastly check sequence
             return ExtendedFieldElement(
                 uniutil.FiniteFieldPolynomial(enumerate(seed), self.basefield),
                 self)
         except TypeError:
             raise TypeError("seed %s is not an appropriate object." % str(seed))
예제 #8
0
 def _random_irriducible(char, degree):
     """
     Return randomly chosen irreducible polynomial of self.degree.
     """
     cardinality = char**degree
     basefield = FinitePrimeField.getInstance(char)
     seed = bigrandom.randrange(1, char) + cardinality
     cand = uniutil.FiniteFieldPolynomial(enumerate(
         arith1.expand(seed, cardinality)),
                                          coeffring=basefield)
     while cand.degree() < degree or not cand.isirreducible():
         seed = bigrandom.randrange(1, cardinality) + cardinality
         cand = uniutil.FiniteFieldPolynomial(enumerate(
             arith1.expand(seed, cardinality)),
                                              coeffring=basefield)
     _log.debug(cand.order.format(cand))
     return cand
예제 #9
0
 def __init__(self, characteristic, n_or_modulus):
     """
     FiniteExtendedField(p, n_or_modulus) creates a finite field.
     characteristic must be prime. n_or_modulus can be:
       1) an integer greater than 1, or
       2) a polynomial in a polynomial ring of F_p with degree
          greater than 1.
     """
     FiniteField.__init__(self, characteristic)
     self.basefield = FinitePrimeField.getInstance(self.char)
     if isinstance(n_or_modulus, int):
         if n_or_modulus <= 1:
             raise ValueError("degree of extension must be > 1.")
         self.degree = n_or_modulus
         # randomly chosen irreducible polynomial
         top = FinitePrimeFieldPolynomial({self.degree: 1},
                                          coeffring=self.basefield)
         seed = bigrandom.randrange(1, self.char)
         cand = FinitePrimeFieldPolynomial(enumerate(
             arith1.expand(seed, self.char)),
                                           coeffring=self.basefield) + top
         while cand.degree() < self.degree or not cand.isirreducible():
             seed = bigrandom.randrange(1, self.char**self.degree)
             cand = FinitePrimeFieldPolynomial(
                 enumerate(arith1.expand(seed, self.char)),
                 coeffring=self.basefield) + top
         self.modulus = cand
     elif isinstance(n_or_modulus, FinitePrimeFieldPolynomial):
         if isinstance(n_or_modulus.getCoefficientRing(), FinitePrimeField):
             if n_or_modulus.degree() > 1 and n_or_modulus.isirreducible():
                 self.degree = n_or_modulus.degree()
                 self.modulus = n_or_modulus
             else:
                 raise ValueError(
                     "modulus must be of degree greater than 1.")
         else:
             raise TypeError("modulus must be F_p polynomial.")
     else:
         raise TypeError("degree or modulus must be supplied.")
     self.registerModuleAction(rational.theIntegerRing, self._int_mul)
     self.registerModuleAction(FinitePrimeField.getInstance(self.char),
                               self._fp_mul)
예제 #10
0
 def mul(self, k, P):
     """
     this returns [k]*P
     """
     if k >= 0:
         l = arith1.expand(k, 2)
         Q = [0]
         for j in range(len(l) - 1, -1, -1):
             Q = self.add(Q, Q)
             if l[j] == 1:
                 Q = self.add(Q, P)
         return Q
     else:
         return self.sub([0], self.mul(-k, P))
예제 #11
0
파일: ecpp.py 프로젝트: nickspoon/part-ii
 def mul(self, k, P):
     """
     this returns [k]*P
     """
     if k >= 0:
         l = arith1.expand(k, 2)
         Q = [0]
         for j in range(len(l) - 1, -1, -1):
             Q = self.add(Q, Q)
             if l[j] == 1:
                 Q = self.add(Q, P)
         return Q
     else:
         return self.sub([0], self.mul(-k, P))
예제 #12
0
 def _small_irriducible(char, degree):
     """
     Return an irreducible polynomial of self.degree with a small
     number of non-zero coefficients.
     """
     cardinality = char ** degree
     basefield = FinitePrimeField.getInstance(char)
     top = uniutil.polynomial({degree: 1}, coeffring=basefield)
     for seed in range(degree - 1):
         for const in range(1, char):
             coeffs = [const] + arith1.expand(seed, 2)
             cand = uniutil.polynomial(enumerate(coeffs), coeffring=basefield) + top
             if cand.isirreducible():
                 _log.debug(cand.order.format(cand))
                 return cand
     for subdeg in range(degree):
         subseedbound = char ** subdeg
         for subseed in range(subseedbound + 1, char * subseedbound):
             if not subseed % char:
                 continue
             seed = subseed + cardinality
             cand = uniutil.polynomial(enumerate(arith1.expand(seed, cardinality)), coeffring=basefield)
             if cand.isirreducible():
                 return cand
예제 #13
0
def _lucas_chain(n, f, g, x_0, x_1):
    """
    Given an integer n, two functions f and g, and initial value (x_0, x_1),
    compute (x_n, x_{n+1}), where the sequence {x_i} is defined as:
      x_{2i} = f(x_i)
      x_{2i+1} = g(x_i, x_{i+1})
    """
    binary = arith1.expand(n, 2)
    u = x_0
    v = x_1
    while binary:
        if 1 == binary.pop():
            u, v = g(u, v), f(v)
        else:
            u, v = f(u), g(u, v)
    return u, v
예제 #14
0
파일: prime.py 프로젝트: nickspoon/part-ii
def Lucas_chain(n, f, g, x_0, x_1):
    """
    Given an integer n, two functions f and g, and initial value (x_0, x_1),
    compute (x_n, x_{n+1}), where the sequence {x_i} is defined as:
      x_{2i} = f(x_i)
      x_{2i+1} = g(x_i, x_{i+1})
    """
    binary = arith1.expand(n, 2)
    u = x_0
    v = x_1
    while binary:
        if 1 == binary.pop():
            u, v = g(u, v), f(v)
        else:
            u, v = f(u), g(u, v)
    return u, v
예제 #15
0
    def __init__(self, p, initial, power):
        """
        PadicInteger(p, initial, power)

        The second argument initial can be either integer or iterable.
        If initial is an integer, it will be expanded p-adically.
        In iterable case, it will be treated as a p-adic expansion.

        The third argument power is a power index of modulus, by which
        the representation is finite.
        """
        if isinstance(initial, int):
            cutoff = p**power
            # taking modulo cutoff is useful for nagative integers.
            self.expansion = tuple(arith1.expand(initial % cutoff, p))
        else:
            # take only first 'power' elements of initial.
            self.expansion = tuple([e for i, e in zip(range(power), initial)])
        self.p = p
예제 #16
0
 def _three_pow(self, element, index):
     """
     powering by using left-right base 3 method.
     """
     digits = arith1.expand(index, 3)
     e = len(digits) - 1
     f = e
     # Precomputation
     pre_table = [element, self.square(element)]
     # Main Loop
     while f >= 0:
         tit = digits[f]
         if f == e:
             sol = pre_table[tit - 1]
         else:
             sol = self.mul(self.square(sol), sol)
             if tit:
                 sol = self.mul(sol, pre_table[tit - 1])
         f -= 1
     return sol
예제 #17
0
 def createElement(self, seed):
     """
     Create an element of the field.
     """
     # FIXME: Undefined variable 'FinitFieldExtensionElement'
     if isinstance(seed, int):
         expansion = arith1.expand(seed, card(self.basefield))
         return FinitFieldExtensionElement(
             polynomial.OneVariableDensePolynomial(expansion, "#1",
                                                   self.basefield), self)
     elif isinstance(seed, polynomial.OneVariablePolynomial):
         return FiniteFieldExtensionElement(seed("#1"), self)
     else:
         try:
             # lastly check sequence
             return FiniteFieldExtensionElement(
                 polynomial.OneVariableDensePolynomial(
                     list(seed), "#1", self.basefield), self)
         except TypeError:
             raise TypeError("seed %s is not an appropriate object." %
                             str(seed))
예제 #18
0
 def testExpand(self):
     self.assertEqual(
         [0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1],
         arith1.expand(10**6, 2))
     self.assertEqual([1, 1, 3, 3, 3, 3, 1, 1], arith1.expand(10**6, 7))