Exemple #1
0
    def decode_from_hex(self, hex_str, unhex=True):

        ba = None
        if unhex:
            ba = bytearray(binascii.unhexlify(hex_str))
        else:
            ba = hex_str

        cq = self.field.p

        expected_byte_len = int((_bitlength(cq) + 7) / 8)

        f = ba[0]

        if f == 0:
            return self.Infinity

        # these are compressed
        if f == 2 or f == 3:
            if len(ba) != expected_byte_len + 1:
                raise Exception("Incorrrect length for encoding")
            yTilde = f & 1
            data = bytearray(ba[1:])
            data.reverse()
            data.append(0)
            X1 = int.from_bytes(data, 'little')
            return self.decompress_from_curve(X1, yTilde)

        #uncompressed or hybrid
        elif f == 4 or f == 6 or f == 7:
            raise NotImplementedError()

        raise Exception("Invalid point incoding: %s " % f)
Exemple #2
0
    def decode_from_hex(self, hex_str, unhex=True):
        """
        Raises:
            ValueError: if the hex_str is an incorrect length for encoding or compressed encoding
            NotImplementedError: if an unsupported point encoding is used
            TypeError: if unexpected encoding is read
        """
        ba = None
        if unhex:
            ba = bytearray(binascii.unhexlify(hex_str))
        else:
            ba = hex_str

        cq = self.field.p

        expected_byte_len = int((_bitlength(cq) + 7) / 8)

        f = ba[0]

        if f == 0:
            return self.Infinity

        # these are compressed
        if f == 2 or f == 3:
            if len(ba) != expected_byte_len + 1:
                raise ValueError("Incorrect length for encoding")
            yTilde = f & 1
            data = bytearray(ba[1:])
            data.reverse()
            data.append(0)
            X1 = int.from_bytes(data, 'little')
            return self.decompress_from_curve(X1, yTilde)

        # uncompressed or hybrid
        elif f == 4:

            if len(ba) != (2 * expected_byte_len) + 1:
                raise ValueError("Incorrect length for compressed encoding")

            x_data = bytearray(ba[1:1 + expected_byte_len])
            x_data.reverse()
            x_data.append(0)

            y_data = bytearray(ba[1 + expected_byte_len:])
            y_data.reverse()
            y_data.append(0)

            x = int.from_bytes(x_data, 'little')
            y = int.from_bytes(y_data, 'little')

            pnt = self.point(x, y)
            return pnt

        elif f == 6 or f == 7:
            raise NotImplementedError()

        else:
            raise ValueError(f"Invalid point encoding: {f}")
Exemple #3
0
def _lucas_sequence(n, P, Q, k):
    """Return the modular Lucas sequence (U_k, V_k, Q_k).

    Given a Lucas sequence defined by P, Q, returns the kth values for
    U and V, along with Q^k, all modulo n.  This is intended for use with
    possibly very large values of n and k, where the combinatorial functions
    would be completely unusable.

    The modular Lucas sequences are used in numerous places in number theory,
    especially in the Lucas compositeness tests and the various n + 1 proofs.

    Examples
    ========

    >>> from sympy.ntheory.primetest import _lucas_sequence
    >>> N = 10**2000 + 4561
    >>> sol = U, V, Qk = _lucas_sequence(N, 3, 1, N//2); sol
    (0, 2, 1)

    """
    D = P * P - 4 * Q
    if n < 2:
        raise ValueError("n must be >= 2")
    if k < 0:
        raise ValueError("k must be >= 0")
    if D == 0:
        raise ValueError("D must not be zero")

    if k == 0:
        return _int_tuple(0, 2, Q)
    U = 1
    V = P
    Qk = Q
    b = _bitlength(k)
    if Q == 1:
        # Optimization for extra strong tests.
        while b > 1:
            U = (U * V) % n
            V = (V * V - 2) % n
            b -= 1
            if (k >> (b - 1)) & 1:
                U, V = U * P + V, V * P + U * D
                if U & 1:
                    U += n
                if V & 1:
                    V += n
                U, V = U >> 1, V >> 1
    elif P == 1 and Q == -1:
        # Small optimization for 50% of Selfridge parameters.
        while b > 1:
            U = (U * V) % n
            if Qk == 1:
                V = (V * V - 2) % n
            else:
                V = (V * V + 2) % n
                Qk = 1
            b -= 1
            if (k >> (b - 1)) & 1:
                U, V = U + V, V + U * D
                if U & 1:
                    U += n
                if V & 1:
                    V += n
                U, V = U >> 1, V >> 1
                Qk = -1
    else:
        # The general case with any P and Q.
        while b > 1:
            U = (U * V) % n
            V = (V * V - 2 * Qk) % n
            Qk *= Qk
            b -= 1
            if (k >> (b - 1)) & 1:
                U, V = U * P + V, V * P + U * D
                if U & 1:
                    U += n
                if V & 1:
                    V += n
                U, V = U >> 1, V >> 1
                Qk *= Q
            Qk %= n
    return _int_tuple(U % n, V % n, Qk)
Exemple #4
0
def _lucas_sequence(n, P, Q, k):
    """Return the modular Lucas sequence (U_k, V_k, Q_k).
    Given a Lucas sequence defined by P, Q, returns the kth values for
    U and V, along with Q^k, all modulo n.
    """
    D = P * P - 4 * Q
    if n < 2:
        raise ValueError("n must be >= 2")
    if k < 0:
        raise ValueError("k must be >= 0")
    if D == 0:
        raise ValueError("D must not be zero")

    if k == 0:
        return 0, 2
    U = 1
    V = P
    Qk = Q
    b = _bitlength(k)
    if Q == 1:
        # For strong tests
        while b > 1:
            U = (U * V) % n
            V = (V * V - 2) % n
            b -= 1
            if (k >> (b - 1)) & 1:
                t = U * D
                U = U * P + V
                if U & 1:
                    U += n
                U >>= 1
                V = V * P + t
                if V & 1:
                    V += n
                V >>= 1
    elif P == 1 and Q == -1:
        # For Selfridge parameters
        while b > 1:
            U = (U * V) % n
            if Qk == 1:
                V = (V * V - 2) % n
            else:
                V = (V * V + 2) % n
                Qk = 1
            b -= 1
            if (k >> (b - 1)) & 1:
                t = U * D
                U = U + V
                if U & 1:
                    U += n
                U >>= 1
                V = V + t
                if V & 1:
                    V += n
                V >>= 1
                Qk = -1
    else:
        # The general case with any P and Q
        while b > 1:
            U = (U * V) % n
            V = (V * V - 2 * Qk) % n
            Qk *= Qk
            b -= 1
            if (k >> (b - 1)) & 1:
                t = U * D
                U = U * P + V
                if U & 1:
                    U += n
                U >>= 1
                V = V * P + t
                if V & 1:
                    V += n
                V >>= 1
                Qk *= Q
            Qk %= n
    U %= n
    V %= n
    return U, V
Exemple #5
0
def _lucas_sequence(n, P, Q, k):
    """Return the modular Lucas sequence (U_k, V_k, Q_k).

    Given a Lucas sequence defined by P, Q, returns the kth values for
    U and V, along with Q^k, all modulo n.  This is intended for use with
    possibly very large values of n and k, where the combinatorial functions
    would be completely unusable.

    The modular Lucas sequences are used in numerous places in number theory,
    especially in the Lucas compositeness tests and the various n + 1 proofs.

    Examples
    ========

    >>> from sympy.ntheory.primetest import _lucas_sequence
    >>> N = 10**2000 + 4561
    >>> sol = U, V, Qk = _lucas_sequence(N, 3, 1, N//2); sol
    (0, 2, 1)

    """
    D = P*P - 4*Q
    if n < 2:
        raise ValueError("n must be >= 2")
    if k < 0:
        raise ValueError("k must be >= 0")
    if D == 0:
        raise ValueError("D must not be zero")

    if k == 0:
        return _int_tuple(0, 2, Q)
    U = 1
    V = P
    Qk = Q
    b = _bitlength(k)
    if Q == 1:
        # Optimization for extra strong tests.
        while b > 1:
            U = (U*V) % n
            V = (V*V - 2) % n
            b -= 1
            if (k >> (b - 1)) & 1:
                U, V = U*P + V, V*P + U*D
                if U & 1:
                    U += n
                if V & 1:
                    V += n
                U, V = U >> 1, V >> 1
    elif P == 1 and Q == -1:
        # Small optimization for 50% of Selfridge parameters.
        while b > 1:
            U = (U*V) % n
            if Qk == 1:
                V = (V*V - 2) % n
            else:
                V = (V*V + 2) % n
                Qk = 1
            b -= 1
            if (k >> (b-1)) & 1:
                U, V = U + V, V + U*D
                if U & 1:
                    U += n
                if V & 1:
                    V += n
                U, V = U >> 1, V >> 1
                Qk = -1
    else:
        # The general case with any P and Q.
        while b > 1:
            U = (U*V) % n
            V = (V*V - 2*Qk) % n
            Qk *= Qk
            b -= 1
            if (k >> (b - 1)) & 1:
                U, V = U*P + V, V*P + U*D
                if U & 1:
                    U += n
                if V & 1:
                    V += n
                U, V = U >> 1, V >> 1
                Qk *= Q
            Qk %= n
    return _int_tuple(U % n, V % n, Qk)