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)
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}")
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)
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
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)