def galois_field_monic(f, p): lc = f[0] if lc == 1: return list(f) a = invert(lc, p) return [(a * b) % p for b in f]
def bottom_up_scan(ex): if ex.is_Atom: if ex is S.ImaginaryUnit: if ex not in mapping: return update_mapping(ex, 2, 1) else: return symbols[ex] elif ex.is_Rational: return ex elif ex.is_Add: return Add(*[ bottom_up_scan(g) for g in ex.args ]) elif ex.is_Mul: return Mul(*[ bottom_up_scan(g) for g in ex.args ]) elif ex.is_Pow: if ex.exp.is_Rational: if ex.exp < 0 and ex.base.is_Add: coeff, terms = ex.base.as_coeff_add() elt, _ = primitive_element(terms, polys=True) alg = ex.base - coeff # XXX: turn this into eval() inverse = invert(elt.gen + coeff, elt).as_expr() base = inverse.subs(elt.gen, alg).expand() if ex.exp == -1: return bottom_up_scan(base) else: ex = base**(-ex.exp) if not ex.exp.is_Integer: base, exp = ( ex.base**ex.exp.p).expand(), Rational(1, ex.exp.q) else: base, exp = ex.base, ex.exp base = bottom_up_scan(base) expr = base**exp if expr not in mapping: return update_mapping(expr, 1/exp, -base) else: return symbols[expr] elif ex.is_AlgebraicNumber: if ex.root not in mapping: return update_mapping(ex.root, ex.minpoly) else: return symbols[ex.root] raise NotAlgebraic("%s doesn't seem to be an algebraic number" % ex)
def bottom_up_scan(ex): if ex.is_Atom: if ex is S.ImaginaryUnit: if ex not in mapping: return update_mapping(ex, 2, 1) else: return symbols[ex] elif ex.is_Rational: return ex elif ex.is_Add: return Add(*[bottom_up_scan(g) for g in ex.args]) elif ex.is_Mul: return Mul(*[bottom_up_scan(g) for g in ex.args]) elif ex.is_Pow: if ex.exp.is_Rational: if ex.exp < 0 and ex.base.is_Add: coeff, terms = ex.base.as_coeff_add() elt, _ = primitive_element(terms, polys=True) alg = ex.base - coeff # XXX: turn this into eval() inverse = invert(elt.gen + coeff, elt).as_expr() base = inverse.subs(elt.gen, alg).expand() if ex.exp == -1: return bottom_up_scan(base) else: ex = base**(-ex.exp) if not ex.exp.is_Integer: base, exp = (ex.base**ex.exp.p).expand(), Rational( 1, ex.exp.q) else: base, exp = ex.base, ex.exp base = bottom_up_scan(base) expr = base**exp if expr not in mapping: return update_mapping(expr, 1 / exp, -base) else: return symbols[expr] elif ex.is_AlgebraicNumber: if ex.root not in mapping: return update_mapping(ex.root, ex.minpoly) else: return symbols[ex.root] raise NotAlgebraic("%s doesn't seem to be an algebraic number" % ex)
def bottom_up_scan(ex): if ex.is_Atom: if ex is S.ImaginaryUnit: if ex not in mapping: return update_mapping(ex, 2, 1) else: return symbols[ex] elif ex.is_Rational: return ex elif ex.is_Add: return Add(*[bottom_up_scan(g) for g in ex.args]) elif ex.is_Mul: return Mul(*[bottom_up_scan(g) for g in ex.args]) elif ex.is_Pow: if ex.exp.is_Rational: if ex.exp < 0: minpoly_base = _minpoly_groebner(ex.base, x, cls) inverse = invert(x, minpoly_base).as_expr() base_inv = inverse.subs(x, ex.base).expand() if ex.exp == -1: return bottom_up_scan(base_inv) else: ex = base_inv**(-ex.exp) if not ex.exp.is_Integer: base, exp = (ex.base**ex.exp.p).expand(), Rational( 1, ex.exp.q) else: base, exp = ex.base, ex.exp base = bottom_up_scan(base) expr = base**exp if expr not in mapping: return update_mapping(expr, 1 / exp, -base) else: return symbols[expr] elif ex.is_AlgebraicNumber: if ex.root not in mapping: return update_mapping(ex.root, ex.minpoly) else: return symbols[ex.root] raise NotAlgebraic("%s doesn't seem to be an algebraic number" % ex)
def rsa_private_key(p, q, e): r""" The RSA *private key* is the pair `(n,d)`, where `n` is a product of two primes and `d` is the inverse of `e` (mod `\phi(n)`). Examples ======== >>> from sympy.crypto.crypto import rsa_private_key >>> p, q, e = 3, 5, 7 >>> rsa_private_key(p, q, e) (15, 7) """ n = p*q phi = totient(n) if isprime(p) and isprime(q) and gcd(e, phi) == 1: d = int(invert(e,phi)) return n, d return False
def rsa_private_key(p, q, e): r""" The RSA *private key* is the pair `(n,d)`, where `n` is a product of two primes and `d` is the inverse of `e` (mod `\phi(n)`). Examples ======== >>> from sympy.crypto.crypto import rsa_private_key >>> p, q, e = 3, 5, 7 >>> rsa_private_key(p, q, e) (15, 7) """ n = p * q phi = totient(n) if isprime(p) and isprime(q) and gcd(e, phi) == 1: d = int(invert(e, phi)) return n, d return False
def bottom_up_scan(ex): """ Transform a given algebraic expression *ex* into a multivariate polynomial, by introducing fresh variables with defining equations. Explanation =========== The critical elements of the algebraic expression *ex* are root extractions, instances of :py:class:`~.AlgebraicNumber`, and negative powers. When we encounter a root extraction or an :py:class:`~.AlgebraicNumber` we replace this expression with a fresh variable ``a_i``, and record the defining polynomial for ``a_i``. For example, if ``a_0**(1/3)`` occurs, we will replace it with ``a_1``, and record the new defining polynomial ``a_1**3 - a_0``. When we encounter a negative power we transform it into a positive power by algebraically inverting the base. This means computing the minimal polynomial in ``x`` for the base, inverting ``x`` modulo this poly (which generates a new polynomial) and then substituting the original base expression for ``x`` in this last polynomial. We return the transformed expression, and we record the defining equations for new symbols using the ``update_mapping()`` function. """ if ex.is_Atom: if ex is S.ImaginaryUnit: if ex not in mapping: return update_mapping(ex, 2, 1) else: return symbols[ex] elif ex.is_Rational: return ex elif ex.is_Add: return Add(*[bottom_up_scan(g) for g in ex.args]) elif ex.is_Mul: return Mul(*[bottom_up_scan(g) for g in ex.args]) elif ex.is_Pow: if ex.exp.is_Rational: if ex.exp < 0: minpoly_base = _minpoly_groebner(ex.base, x, cls) inverse = invert(x, minpoly_base).as_expr() base_inv = inverse.subs(x, ex.base).expand() if ex.exp == -1: return bottom_up_scan(base_inv) else: ex = base_inv**(-ex.exp) if not ex.exp.is_Integer: base, exp = (ex.base**ex.exp.p).expand(), Rational( 1, ex.exp.q) else: base, exp = ex.base, ex.exp base = bottom_up_scan(base) expr = base**exp if expr not in mapping: if exp.is_Integer: return expr.expand() else: return update_mapping(expr, 1 / exp, -base) else: return symbols[expr] elif ex.is_AlgebraicNumber: if ex not in mapping: return update_mapping(ex, ex.minpoly_of_element()) else: return symbols[ex] raise NotAlgebraic("%s does not seem to be an algebraic number" % ex)