def compare(x, y_enc, l, pk):

    x_b = get_bits(x, l)
    x_enc = []
    for b in x_b:
        x_enc.append(dgk.encrypt(b, pub))
    x_enc = np.array(x_enc)
    one_enc = dgk.encrypt(1, pub)
    xxory = []

    for i in range(l):
        if x_b[i] == 0:
            xxory.append(y_enc[i])
        else:
            xxory.append(
                ((one_enc % pub['n']) *
                 (mod_inverse(y_enc[i], pub['n']) % pub['n'])) % pub['n'])
    xxory = np.array(xxory)

    dela = np.random.randint(0, 2)
    s = 1 - 2 * dela
    s_enc = dgk.encrypt(s, pub)

    # precompute xor cubes
    xor3precomp = [1] * l
    i = l - 2
    while (i >= 0):
        xor3precomp[i] = ((pow(xxory[i + 1], 3, pub['n']) % pub['n']) *
                          (xor3precomp[i + 1] % pub['n'])) % pub['n']
        i -= 1
    # compute [c]
    c = []
    for i in range(l):
        temp = ((s_enc % pub['n']) * (x_enc[i] % pub['n']) *
                (mod_inverse(y_enc[i], pub['n'])) % pub['n'] *
                (xor3precomp[i] % pub['n'])) % pub['n']
        r = np.random.randint(1, pub['u'])
        r_dash = random.getrandbits(int(2.5 * pub['t']))
        temp = (pow(temp, r, pub['n']) *
                pow(pub['h'], r_dash, pub['n'])) % pub['n']
        c.append(temp)
    c = np.array(c)
    # shuffle c
    np.random.shuffle(c)

    N, _ = pk

    c1 = gm.encrypt(dela, pk)

    one = gm.encrypt(1, pk)

    c1_bit = list(c1)[0]

    one_bit = list(one)[0]

    ##############################################################################################################
    c2_bit = step2_B(c, pk)
    ##############################################################################################################

    return (((c1_bit % N * c2_bit % N) % N) * one_bit % N) % N
Example #2
0
 def __eq__(self, other):
     """Two points are equal if X/Z of both points are equal
     """
     if self.a_24 != other.a_24 or self.mod != other.mod:
         return False
     return self.x_cord * mod_inverse(self.z_cord, self.mod) % self.mod ==\
         other.x_cord * mod_inverse(other.z_cord, self.mod) % self.mod
Example #3
0
def parameters():
    # Initialize variables to 0
    q = 0
    p = 0
    e = 0

    # Generate 512 bit prime q
    q = safeprime()

    # Generate 512 bit prime p
    p = safeprime()

    # Calculate N and eulers number
    N = p * q
    euler = (p - 1) * (q - 1)

    # Calculate e
    while (gcd(e, euler) != 1):
        e = random.randrange(1, euler)

    # Solve linear congruence
    d = mod_inverse(e, euler)
    #d = modInv(e, euler)

    # Gen public key pair
    public_key = (N, e)

    # Gen private key pair
    private_key = (d, p, q)

    return (public_key, private_key)
Example #4
0
def _help(m, prime_modulo_method, diff_method, expr_val):
    """
    Helper function for _nthroot_mod_composite and polynomial_congruence.

    Parameters
    ==========

    m : positive integer
    prime_modulo_method : function to calculate the root of the congruence
    equation for the prime divisors of m
    diff_method : function to calculate derivative of expression at any
    given point
    expr_val : function to calculate value of the expression at any
    given point
    """
    from sympy.ntheory.modular import crt

    f = factorint(m)
    dd = {}
    for p, e in f.items():
        tot_roots = set()
        if e == 1:
            tot_roots.update(prime_modulo_method(p))
        else:
            for root in prime_modulo_method(p):
                diff = diff_method(root, p)
                if diff != 0:
                    ppow = p
                    m_inv = mod_inverse(diff, p)
                    for j in range(1, e):
                        ppow *= p
                        root = (root - expr_val(root, ppow) * m_inv) % ppow
                    tot_roots.add(root)
                else:
                    new_base = p
                    roots_in_base = {root}
                    while new_base < pow(p, e):
                        new_base *= p
                        new_roots = set()
                        for k in roots_in_base:
                            if expr_val(k, new_base) != 0:
                                continue
                            while k not in new_roots:
                                new_roots.add(k)
                                k = (k + (new_base // p)) % new_base
                        roots_in_base = new_roots
                    tot_roots = tot_roots | roots_in_base
        if tot_roots == set():
            return []
        dd[pow(p, e)] = tot_roots
    a = []
    m = []
    for x, y in dd.items():
        m.append(x)
        a.append(list(y))
    return sorted(set(crt(m, list(i))[0] for i in cartes(*a)))
Example #5
0
def encrypt(m, pub):
	neg = False
	if(m < 0):
		m = -m
		neg = True
	r = random.getrandbits(int(2.5*pub['t']))
	c = (pow(pub['g'], m, pub['n']) * pow(pub['h'], r, pub['n'])) % pub['n']
	if(neg):
		c = mod_inverse(c, pub['n'])
	return c
 def get_inverse(self, element):
     # Gets the inverse of an element in the ring using Geometric progression
     summands = self.get_summands(element)
     zero_deg_comp = self.get_zero_degree_component(summands)
     zero_deg_comp_inv = mod_inverse(zero_deg_comp, self.p)
     positive_deg_comp = sum(summands) - zero_deg_comp
     if not positive_deg_comp:
         return zero_deg_comp_inv
     inverse = zero_deg_comp_inv*sum((-zero_deg_comp_inv*positive_deg_comp)**i for i in range(self.p*len(summands[:-1])))
     return self.coefs_mod_p(self.eliminate_exp_over_p(inverse))
Example #7
0
    def intt(self):
        """
        Compute IFFT in finite feild.
        The algorithm is the same as NTT, but it need to change w to w^(-1) 
        and multiply N^(-1) for each coefficient of polynomial.
        input: FFT(poly), primitive nth root of unity
        output: polynomial
        complexity: (N/2 log N)
        """

        inv_w = mod_inverse(self.w, self.mod)
        inv_N = mod_inverse(self.N, self.mod)

        poly = self.ntt(self.fft_poly, inv_w)

        for i in range(0, self.N):
            poly[i] = poly[i] * inv_N % self.mod

        # if it is computed over Z[x]/<x^n+1>, it should multiply phi^(-1)
        if self.ideal:
            inv_phi = mod_inverse(self.phi, self.mod)
            poly = self.mulPhi(poly, inv_phi)

        return poly
Example #8
0
def _discrete_log_pohlig_hellman(n, a, b, order=None):
    """
    Pohlig-Hellman algorithm for computing the discrete logarithm of ``a`` to
    the base ``b`` modulo ``n``.

    In order to compute the discrete logarithm, the algorithm takes advantage
    of the factorization of the group order. It is more efficient when the
    group order factors into many small primes.

    Examples
    ========

    >>> from sympy.ntheory.residue_ntheory import _discrete_log_pohlig_hellman
    >>> _discrete_log_pohlig_hellman(251, 210, 71)
    197

    See Also
    ========

    discrete_log

    References
    ==========

    .. [1] "Handbook of applied cryptography", Menezes, A. J., Van, O. P. C., &
        Vanstone, S. A. (1997).
    """
    from .modular import crt

    a %= n
    b %= n

    if order is None:
        order = n_order(b, n)

    f = factorint(order)
    l = [0] * len(f)

    for i, (pi, ri) in enumerate(f.items()):
        for j in range(ri):
            gj = pow(b, l[i], n)
            aj = pow(a * mod_inverse(gj, n), order // pi ** (j + 1), n)
            bj = pow(b, order // pi, n)
            cj = discrete_log(n, aj, bj, pi, True)
            l[i] += cj * pi ** j

    d, _ = crt([pi ** ri for pi, ri in f.items()], l)
    return d
def _discrete_log_pohlig_hellman(n, a, b, order=None):
    """
    Pohlig-Hellman algorithm for computing the discrete logarithm of ``a`` to
    the base ``b`` modulo ``n``.

    In order to compute the discrete logarithm, the algorithm takes advantage
    of the factorization of the group order. It is more efficient when the
    group order factors into many small primes.

    References
    ==========

    .. [1] "Handbook of applied cryptography", Menezes, A. J., Van, O. P. C., &
        Vanstone, S. A. (1997).

    Examples
    ========

    >>> from sympy.ntheory.residue_ntheory import _discrete_log_pohlig_hellman
    >>> _discrete_log_pohlig_hellman(251, 210, 71)
    197

    See also
    ========

    discrete_log
    """
    from .modular import crt
    a %= n
    b %= n

    if order is None:
        order = n_order(b, n)

    f = factorint(order)
    l = [0] * len(f)

    for i, (pi, ri) in enumerate(f.items()):
        for j in range(ri):
            gj = pow(b, l[i], n)
            aj = pow(a * mod_inverse(gj, n), order // pi**(j + 1), n)
            bj = pow(b, order // pi, n)
            cj = discrete_log(n, aj, bj, pi, True)
            l[i] += cj * pi**j

    d, _ = crt([pi**ri for pi, ri in f.items()], l)
    return d
Example #10
0
def quadratic_congruence(a, b, c, p):
    """
    Find the solutions to ``a x**2 + b x + c = 0 mod p
    a : integer
    b : integer
    c : integer
    p : positive integer
    """
    from sympy.polys.galoistools import linear_congruence

    a = as_int(a)
    b = as_int(b)
    c = as_int(c)
    p = as_int(p)
    a = a % p
    b = b % p
    c = c % p

    if a == 0:
        return linear_congruence(b, -c, p)
    if p == 2:
        roots = []
        if c % 2 == 0:
            roots.append(0)
        if (a + b + c) % 2 == 0:
            roots.append(1)
        return roots
    if isprime(p):
        inv_a = mod_inverse(a, p)
        b *= inv_a
        c *= inv_a
        if b % 2 == 1:
            b = b + p
        d = ((b * b) // 4 - c) % p
        y = sqrt_mod(d, p, all_roots=True)
        res = set()
        for i in y:
            res.add((i - b // 2) % p)
        return sorted(res)
    y = sqrt_mod(b * b - 4 * a * c, 4 * a * p, all_roots=True)
    res = set()
    for i in y:
        root = linear_congruence(2 * a, i - b, 4 * a * p)
        for j in root:
            res.add(j % p)
    return sorted(res)
Example #11
0
def test_Point():
    from sympy.core.numbers import mod_inverse
    #The curve is of the form y**2 = x**3 + a*x**2 + x
    mod = 101
    a = 10
    a_24 = (a + 2)*mod_inverse(4, mod)
    p1 = Point(10, 17, a_24, mod)
    p2 = p1.double()
    assert p2 == Point(68, 56, a_24, mod)
    p4 = p2.double()
    assert p4 == Point(22, 64, a_24, mod)
    p8 = p4.double()
    assert p8 == Point(71, 95, a_24, mod)
    p16 = p8.double()
    assert p16 == Point(5, 16, a_24, mod)
    p32 = p16.double()
    assert p32 == Point(33, 96, a_24, mod)

    # p3 = p2 + p1
    p3 = p2.add(p1, p1)
    assert p3 == Point(1, 61, a_24, mod)
    # p5 = p3 + p2 or p4 + p1
    p5 = p3.add(p2, p1)
    assert p5 == Point(49, 90, a_24, mod)
    assert p5 == p4.add(p1, p3)
    # p6 = 2*p3
    p6 = p3.double()
    assert p6 == Point(87, 43, a_24, mod)
    assert p6 == p4.add(p2, p2)
    # p7 = p5 + p2
    p7 = p5.add(p2, p3)
    assert p7 == Point(69, 23, a_24, mod)
    assert p7 == p4.add(p3, p1)
    assert p7 == p6.add(p1, p5)
    # p9 = p5 + p4
    p9 = p5.add(p4, p1)
    assert p9 == Point(56, 99, a_24, mod)
    assert p9 == p6.add(p3, p3)
    assert p9 == p7.add(p2, p5)
    assert p9 == p8.add(p1, p7)

    assert p5 == p1.mont_ladder(5)
    assert p9 == p1.mont_ladder(9)
    assert p16 == p1.mont_ladder(16)
    assert p9 == p3.mont_ladder(3)
Example #12
0
def _inv_mod(M, m):
    r"""
    Returns the inverse of the matrix `K` (mod `m`), if it exists.

    Method to find the matrix inverse of `K` (mod `m`) implemented in this function:

    * Compute `\mathrm{adj}(K) = \mathrm{cof}(K)^t`, the adjoint matrix of `K`.

    * Compute `r = 1/\mathrm{det}(K) \pmod m`.

    * `K^{-1} = r\cdot \mathrm{adj}(K) \pmod m`.

    Examples
    ========

    >>> from sympy import Matrix
    >>> A = Matrix(2, 2, [1, 2, 3, 4])
    >>> A.inv_mod(5)
    Matrix([
    [3, 1],
    [4, 2]])
    >>> A.inv_mod(3)
    Matrix([
    [1, 1],
    [0, 1]])

    """

    if not M.is_square:
        raise NonSquareMatrixError()

    N = M.cols
    det_K = M.det()
    det_inv = None

    try:
        det_inv = mod_inverse(det_K, m)
    except ValueError:
        raise NonInvertibleMatrixError('Matrix is not invertible (mod %d)' % m)

    K_adj = M.adjugate()
    K_inv = M.__class__(
        N, N, [det_inv * K_adj[i, j] % m for i in range(N) for j in range(N)])

    return K_inv
Example #13
0
def _discrete_log_shanks_steps(n, a, b, order=None):
    """
    Baby-step giant-step algorithm for computing the discrete logarithm of
    ``a`` to the base ``b`` modulo ``n``.

    The algorithm is a time-memory trade-off of the method of exhaustive
    search. It uses `O(sqrt(m))` memory, where `m` is the group order.

    Examples
    ========

    >>> from sympy.ntheory.residue_ntheory import _discrete_log_shanks_steps
    >>> _discrete_log_shanks_steps(41, 15, 7)
    3

    See Also
    ========

    discrete_log

    References
    ==========

    .. [1] "Handbook of applied cryptography", Menezes, A. J., Van, O. P. C., &
        Vanstone, S. A. (1997).
    """
    a %= n
    b %= n
    if order is None:
        order = n_order(b, n)
    m = isqrt(order) + 1
    T = dict()
    x = 1
    for i in range(m):
        T[x] = i
        x = x * b % n
    z = mod_inverse(b, n)
    z = pow(z, m, n)
    x = a
    for i in range(m):
        if x in T:
            return i * m + T[x]
        x = x * z % n
    raise ValueError("Log does not exist")
Example #14
0
def _discrete_log_shanks_steps(n, a, b, order=None):
    """
    Baby-step giant-step algorithm for computing the discrete logarithm of
    ``a`` to the base ``b`` modulo ``n``.

    The algorithm is a time-memory trade-off of the method of exhaustive
    search. It uses `O(sqrt(m))` memory, where `m` is the group order.

    References
    ==========

    .. [1] "Handbook of applied cryptography", Menezes, A. J., Van, O. P. C., &
        Vanstone, S. A. (1997).

    Examples
    ========

    >>> from sympy.ntheory.residue_ntheory import _discrete_log_shanks_steps
    >>> _discrete_log_shanks_steps(41, 15, 7)
    3

    See also
    ========

    discrete_log
    """
    a %= n
    b %= n
    if order is None:
        order = n_order(b, n)
    m = isqrt(order) + 1
    T = dict()
    x = 1
    for i in range(m):
        T[x] = i
        x = x * b % n
    z = mod_inverse(b, n)
    z = pow(z, m, n)
    x = a
    for i in range(m):
        if x in T:
            return i * m + T[x]
        x = x * z % n
    raise ValueError("Log does not exist")
Example #15
0
def _nthroot_mod_composite(a, n, m):
    """
    Find the solutions to ``x**n = a mod m`` when m is not prime.
    """
    from sympy.ntheory.modular import crt
    f = factorint(m)
    dd = {}
    for p, e in f.items():
        tot_roots = set()
        if e == 1:
            tot_roots.update(nthroot_mod(a, n, p, True) or [])
        else:
            for root in nthroot_mod(a, n, p, True) or []:
                rootn = pow(root, n)
                diff = (rootn // (root or 1) * n) % p
                if diff != 0:
                    ppow = p
                    for j in range(1, e):
                        ppow *= p
                        root = (root - (rootn - a) * mod_inverse(diff, p)) % ppow
                    tot_roots.add(root)
                else:
                    new_base = p
                    roots_in_base = {root}
                    while new_base < pow(p, e):
                        new_base *= p
                        new_roots = set()
                        for k in roots_in_base:
                            if (pow(k, n) - a) % (new_base) != 0:
                                continue
                            while k not in new_roots:
                                new_roots.add(k)
                                k = (k + (new_base // p)) % new_base
                        roots_in_base = new_roots
                    tot_roots = tot_roots | roots_in_base
        dd[pow(p, e)] = tot_roots
    a = []
    m = []
    for x, y in dd.items():
        m.append(x)
        a.append(list(y))
    return sorted(set(crt(m, list(i))[0] for i in cartes(*a)))
Example #16
0
if pubkey.has_private():
    print("The passed key is a private key")
    sys.exit(1)

# Factorize the modulus (the most ridiculous part!)
modulus = pubkey.n
print("Factorizing (It takes years :( ) ")
l = primefactors(modulus)
print("Done :)")

# Generate private key from the factors
print("Generating the private key")
prime1 = l[1]  # prime1 > prime2
prime2 = l[0]
public_exp = pubkey.e
private_exp = mod_inverse(public_exp, (prime1-1)*(prime2-1))
# coef = Integer(prime2).invert(prime1)
# print(f"modulus: {prime1 * prime2}")
# print(f"publicExponent: {public_exp}");
# print(f"privateExponent: {private_exp}");
# print(f"prime1: {prime1}");
# print(f"prime2: {prime2}");
# print(f"coefficient: {coef}");
key_components = (pubkey.n, public_exp, private_exp, prime1, prime2)  # , coef)
prikey = RSA.construct(key_components)

# Write the generated private key
outfilename = f"{sys.argv[1]}.out.pem"
print(f"Writing the private key to {outfilename}")
with open(outfilename, 'wb') as f:
    f.write(prikey.export_key('PEM'))
Example #17
0
def _initialize_first_polynomial(N, M, factor_base, idx_1000, idx_5000):
    """This step is the initialization of the 1st sieve polynomial.
    Here `a` is selected as a product of several primes of the factor_base
    such that `a` is about to ``sqrt(2*N) / M``. Other initial values of
    factor_base elem are also intialized which includes a_inv, b_ainv, soln1,
    soln2 which are used when the sieve polynomial is changed. The b_ainv
    is required for fast polynomial change as we don't have to calculate
    `2*b*mod_inverse(a, prime)` every time.
    We also ensure that the `factor_base` primes which make `a` are between
    1000 and 5000.

    Parameters:
    ===========

    N : Number to be factored
    M : sieve interval
    factor_base : factor_base primes
    idx_1000 : index of prime numbe in the factor_base near 1000
    idx_5000 : index of primenumber in the factor_base near to 5000
    """
    approx_val = sqrt(2 * N) / M
    # `a` is a parameter of the sieve polynomial and `q` is the prime factors of `a`
    # randomly search for a combination of primes whose multiplication is close to approx_val
    # This multiplication of primes will be `a` and the primes will be `q`
    # `best_a` denotes that `a` is close to approx_val in the random search of combination
    best_a, best_q, best_ratio = None, None, None
    start = 0 if idx_1000 is None else idx_1000
    end = len(factor_base) - 1 if idx_5000 is None else idx_5000
    for _ in range(50):
        a = 1
        q = []
        while (a < approx_val):
            rand_p = 0
            while (rand_p == 0 or rand_p in q):
                rand_p = random.randint(start, end)
            p = factor_base[rand_p].prime
            a *= p
            q.append(rand_p)
        ratio = a / approx_val
        if best_ratio is None or abs(ratio - 1) < abs(best_ratio - 1):
            best_q = q
            best_a = a
            best_ratio = ratio

    a = best_a
    q = best_q

    B = []
    for idx, val in enumerate(q):
        q_l = factor_base[val].prime
        gamma = factor_base[val].tmem_p * mod_inverse(a // q_l, q_l) % q_l
        if gamma > q_l / 2:
            gamma = q_l - gamma
        B.append(a // q_l * gamma)

    b = sum(B)
    g = SievePolynomial([a * a, 2 * a * b, b * b - N], a, b)

    for fb in factor_base:
        if a % fb.prime == 0:
            continue
        fb.a_inv = mod_inverse(a, fb.prime)
        fb.b_ainv = [2 * b_elem * fb.a_inv % fb.prime for b_elem in B]
        fb.soln1 = (fb.a_inv * (fb.tmem_p - b)) % fb.prime
        fb.soln2 = (fb.a_inv * (-fb.tmem_p - b)) % fb.prime
    return g, B
Example #18
0
def _trial_division_stage(N, M, factor_base, sieve_array, sieve_poly,
                          partial_relations, ERROR_TERM):
    """Trial division stage. Here we trial divide the values generetated
    by sieve_poly in the sieve interval and if it is a smooth number then
    it is stored in `smooth_relations`. Moreover, if we find two partial relations
    with same large prime then they are combined to form a smooth relation.
    First we iterate over sieve array and look for values which are greater
    than accumulated_val, as these values have a high chance of being smooth
    number. Then using these values we find smooth relations.
    In general, let ``t**2 = u*p modN`` and ``r**2 = v*p modN`` be two partial relations
    with the same large prime p. Then they can be combined ``(t*r/p)**2 = u*v modN``
    to form a smooth relation.

    Parameters:
    ===========

    N : Number to be factored
    M : sieve interval
    factor_base : factor_base primes
    sieve_array : stores log_p values
    sieve_poly : polynomial from which we find smooth relations
    partial_relations : stores partial relations with one large prime
    ERROR_TERM : error term for accumulated_val
    """
    sqrt_n = sqrt(float(N))
    accumulated_val = log(M * sqrt_n) * 2**10 - ERROR_TERM
    smooth_relations = []
    proper_factor = set()
    partial_relation_upper_bound = 128 * factor_base[-1].prime
    for idx, val in enumerate(sieve_array):
        if val < accumulated_val:
            continue
        x = idx - M
        v = sieve_poly.eval(x)
        vec, is_smooth = _check_smoothness(v, factor_base)
        if is_smooth is None:  #Neither smooth nor partial
            continue
        u = sieve_poly.a * x + sieve_poly.b
        # Update the partial relation
        # If 2 partial relation with same large prime is found then generate smooth relation
        if is_smooth is False:  #partial relation found
            large_prime = vec
            #Consider the large_primes under 128*F
            if large_prime > partial_relation_upper_bound:
                continue
            if large_prime not in partial_relations:
                partial_relations[large_prime] = (u, v)
                continue
            else:
                u_prev, v_prev = partial_relations[large_prime]
                partial_relations.pop(large_prime)
                try:
                    large_prime_inv = mod_inverse(large_prime, N)
                except ValueError:  #if large_prine divides N
                    proper_factor.add(large_prime)
                    continue
                u = u * u_prev * large_prime_inv
                v = v * v_prev // (large_prime * large_prime)
                vec, is_smooth = _check_smoothness(v, factor_base)
        #assert u*u % N == v % N
        smooth_relations.append((u, v, vec))
    return smooth_relations, proper_factor
Example #19
0
def dgk_compare_no_priv():
    global config, data

    if not config['dgk_pub'] or config['dgk_priv']:
        print("Key inconsistency for DGK.")
        return Response("", status=404)

    if not data['compare_operand']:
        print("Comparison operand not set.")
        return Response("", status=404)

    pub = config['dgk_pub']
    y_enc = request.json['y_enc']
    l = len(y_enc)

    # get bits
    x_b = get_bits(data['compare_operand'], config['dgk_l'])
    # get encrypted bits
    x_enc = []
    for b in x_b:
        x_enc.append(dgk.encrypt(b, pub))
    x_enc = np.array(x_enc)
    # get encryption of 1
    one_enc = dgk.encrypt(1, pub)
    # get [x xor y]
    xxory = []
    for i in range(l):
        if x_b[i] == 0:
            xxory.append(y_enc[i])
        else:
            xxory.append(
                ((one_enc % pub['n']) *
                 (mod_inverse(y_enc[i], pub['n']) % pub['n'])) % pub['n'])
    xxory = np.array(xxory)

    dela = np.random.randint(0, 2)
    s = 1 - 2 * dela
    s_enc = dgk.encrypt(s, pub)

    # precompute xor cubes
    xor3precomp = [1] * l
    i = l - 2
    while (i >= 0):
        xor3precomp[i] = ((pow(xxory[i + 1], 3, pub['n']) % pub['n']) *
                          (xor3precomp[i + 1] % pub['n'])) % pub['n']
        i -= 1
    # compute [c]
    c = []
    for i in range(l):
        temp = ((s_enc % pub['n']) * (x_enc[i] % pub['n']) *
                (mod_inverse(y_enc[i], pub['n'])) % pub['n'] *
                (xor3precomp[i] % pub['n'])) % pub['n']
        r = np.random.randint(1, pub['u'])
        r_dash = random.getrandbits(int(2.5 * pub['t']))
        temp = (pow(temp, r, pub['n']) *
                pow(pub['h'], r_dash, pub['n'])) % pub['n']
        c.append(temp)
    # shuffle c
    random.shuffle(c)

    return jsonify(c, dela)
def private_key(p, q, e):
    return (p * q, mod_inverse(e, (p - 1) * (q - 1)))
Example #21
0
def _discrete_log_pollard_rho(n, a, b, order=None, retries=10, rseed=None):
    """
    Pollard's Rho algorithm for computing the discrete logarithm of ``a`` to
    the base ``b`` modulo ``n``.

    It is a randomized algorithm with the same expected running time as
    ``_discrete_log_shanks_steps``, but requires a negligible amount of memory.

    References
    ==========

    .. [1] "Handbook of applied cryptography", Menezes, A. J., Van, O. P. C., &
        Vanstone, S. A. (1997).

    Examples
    ========

    >>> from sympy.ntheory.residue_ntheory import _discrete_log_pollard_rho
    >>> _discrete_log_pollard_rho(227, 3**7, 3)
    7

    See also
    ========

    discrete_log
    """
    a %= n
    b %= n

    if order is None:
        order = n_order(b, n)

    prng = Random()
    if rseed is not None:
        prng.seed(rseed)

    for i in range(retries):
        aa = prng.randint(1, order - 1)
        ba = prng.randint(1, order - 1)
        xa = pow(b, aa, n) * pow(a, ba, n) % n

        c = xa % 3
        if c == 0:
            xb = a * xa % n
            ab = aa
            bb = (ba + 1) % order
        elif c == 1:
            xb = xa * xa % n
            ab = (aa + aa) % order
            bb = (ba + ba) % order
        else:
            xb = b * xa % n
            ab = (aa + 1) % order
            bb = ba

        for j in range(order):
            c = xa % 3
            if c == 0:
                xa = a * xa % n
                ba = (ba + 1) % order
            elif c == 1:
                xa = xa * xa % n
                aa = (aa + aa) % order
                ba = (ba + ba) % order
            else:
                xa = b * xa % n
                aa = (aa + 1) % order

            c = xb % 3
            if c == 0:
                xb = a * xb % n
                bb = (bb + 1) % order
            elif c == 1:
                xb = xb * xb % n
                ab = (ab + ab) % order
                bb = (bb + bb) % order
            else:
                xb = b * xb % n
                ab = (ab + 1) % order

            c = xb % 3
            if c == 0:
                xb = a * xb % n
                bb = (bb + 1) % order
            elif c == 1:
                xb = xb * xb % n
                ab = (ab + ab) % order
                bb = (bb + bb) % order
            else:
                xb = b * xb % n
                ab = (ab + 1) % order

            if xa == xb:
                r = (ba - bb) % order
                if r != 0:
                    return mod_inverse(r, order) * (ab - aa) % order
                break

    raise ValueError("Pollard's Rho failed to find logarithm")
Example #22
0
def _ecm_one_factor(n, B1=10000, B2=100000, max_curve=200):
    """Returns one factor of n using
    Lenstra's 2 Stage Elliptic curve Factorization
    with Suyama's Parameterization. Here Montgomery
    arithmetic is used for fast computation of addition
    and doubling of points in elliptic curve.

    This ECM method considers elliptic curves in Montgomery
    form (E : b*y**2*z = x**3 + a*x**2*z + x*z**2) and involves
    elliptic curve operations (mod N), where the elements in
    Z are reduced (mod N). Since N is not a prime, E over FF(N)
    is not really an elliptic curve but we can still do point additions
    and doubling as if FF(N) was a field.

    Stage 1 : The basic algorithm involves taking a random point (P) on an
    elliptic curve in FF(N). The compute k*P using Montgomery ladder algorithm.
    Let q be an unknown factor of N. Then the order of the curve E, |E(FF(q))|,
    might be a smooth number that divides k. Then we have k = l * |E(FF(q))|
    for some l. For any point belonging to the curve E, |E(FF(q))|*P = O,
    hence k*P = l*|E(FF(q))|*P. Thus kP.z_cord = 0 (mod q), and the unknownn
    factor of N (q) can be recovered by taking gcd(kP.z_cord, N).

    Stage 2 : This is a continuation of Stage 1 if k*P != O. The idea utilize
    the fact that even if kP != 0, the value of k might miss just one large
    prime divisor of |E(FF(q))|. In this case we only need to compute the
    scalar multiplication by p to get p*k*P = O. Here a second bound B2
    restrict the size of possible values of p.

    Parameters
    ==========

    n : Number to be Factored
    B1 : Stage 1 Bound
    B2 : Stage 2 Bound
    max_curve : Maximum number of curves generated

    References
    ==========

    .. [1]  Carl Pomerance and Richard Crandall "Prime Numbers:
        A Computational Perspective" (2nd Ed.), page 344
    """
    n = as_int(n)
    if B1 % 2 != 0 or B2 % 2 != 0:
        raise ValueError("The Bounds should be an even integer")
    sieve.extend(B2)

    if isprime(n):
        return n

    from sympy.functions.elementary.miscellaneous import sqrt
    from sympy.polys.polytools import gcd
    curve = 0
    D = int(sqrt(B2))
    beta = [0] * (D + 1)
    S = [0] * (D + 1)
    k = 1
    for p in sieve.primerange(1, B1 + 1):
        k *= pow(p, integer_log(B1, p)[0])
    while (curve <= max_curve):
        curve += 1

        #Suyama's Paramatrization
        sigma = rgen.randint(6, n - 1)
        u = (sigma * sigma - 5) % n
        v = (4 * sigma) % n
        diff = v - u
        u_3 = pow(u, 3, n)

        try:
            C = (pow(diff, 3, n) *
                 (3 * u + v) * mod_inverse(4 * u_3 * v, n) - 2) % n
        except ValueError:
            #If the mod_inverse(4*u_3*v, n) doesn't exist
            return gcd(4 * u_3 * v, n)

        a24 = (C + 2) * mod_inverse(4, n) % n
        Q = Point(u_3, pow(v, 3, n), a24, n)
        Q = Q.mont_ladder(k)
        g = gcd(Q.z_cord, n)

        #Stage 1 factor
        if g != 1 and g != n:
            return g
        #Stage 1 failure. Q.z = 0, Try another curve
        elif g == n:
            continue

        #Stage 2 - Improved Standard Continuation
        S[1] = Q.double()
        S[2] = S[1].double()
        beta[1] = (S[1].x_cord * S[1].z_cord) % n
        beta[2] = (S[2].x_cord * S[2].z_cord) % n

        for d in range(3, D + 1):
            S[d] = S[d - 1].add(S[1], S[d - 2])
            beta[d] = (S[d].x_cord * S[d].z_cord) % n

        g = 1
        B = B1 - 1
        T = Q.mont_ladder(B - 2 * D)
        R = Q.mont_ladder(B)

        for r in range(B, B2, 2 * D):
            alpha = (R.x_cord * R.z_cord) % n
            for q in sieve.primerange(r + 2, r + 2 * D + 1):
                delta = (q - r) // 2
                f = (R.x_cord - S[d].x_cord)*(R.z_cord + S[d].z_cord) -\
                alpha + beta[delta]
                g = (g * f) % n
            #Swap
            T, R = R, R.add(S[D], T)
        g = gcd(n, g)

        #Stage 2 Factor found
        if g != 1 and g != n:
            return g

    #ECM failed, Increase the bounds
    raise ValueError("Increase the bounds")
Example #23
0
def keygen(k, t, l, save_dir, save_in_file=True, gen_dlut=False):

    # generate distinct primes vp and vq
    vp = gensafeprime.generate(t)
    while (1):
        vq = gensafeprime.generate(t)
        if vp != vq:
            break

    # generate u to be the prime just greater than 2^l+2
    u = nextprime(pow(2, l + 2))

    # generate prime p s.t. vp | p-1 and u | p-1
    print("Generating p....")
    while (1):
        temp1 = 2 * u * vp
        sz = k // 2 - temp1.bit_length()
        prand = gensafeprime.generate(sz)
        p = temp1 * prand + 1
        if isprime(p):
            break

    print("Generating q....")
    # generate prime q s.t. vq | q-1 and u | q-1
    while (1):
        temp1 = 2 * u * vq
        sz = k // 2 - temp1.bit_length()
        qrand = gensafeprime.generate(sz)
        q = temp1 * qrand + 1
        if isprime(q):
            break

    # calc n
    n = p * q

    # finding h
    partials_p = [2 * u * vp, 2 * u * prand, 2 * vp * prand, prand * vp * u]
    while (1):
        hrandp = random.randint(0, p - 1)
        if (hrandp == 1 or math.gcd(hrandp, p) != 1):
            continue
        f = False
        for prod in partials_p:
            f = f | (pow(hrandp, prod, p) == 1)
            if (f):
                break
        if (not f):
            break

    partials_q = [2 * u * vq, 2 * u * qrand, 2 * vq * qrand, qrand * vq * u]
    while (1):
        hrandq = random.randint(0, q - 1)
        if (hrandq == 1 or math.gcd(hrandq, q) != 1):
            continue
        f = False
        for prod in partials_q:
            f = f | (pow(hrandq, prod, q) == 1)
            if (f):
                break
        if (not f):
            break

    hrand = (hrandp * q * mod_inverse(q, p) +
             hrandq * p * mod_inverse(p, q)) % n
    h = pow(hrand, 2 * u * prand * qrand, n)

    #finding g
    partials_p = [2 * u * vp, 2 * u * prand, 2 * vp * prand, prand * vp * u]
    while (1):
        grandp = random.randint(0, p - 1)
        if (grandp == 1 or math.gcd(grandp, p) != 1):
            continue
        f = False
        for prod in partials_p:
            f = f | (pow(grandp, prod, p) == 1)  # modp or modp-1
            if (f):
                break
        if (not f):
            break

    partials_q = [2 * u * vq, 2 * u * qrand, 2 * vq * qrand, qrand * vq * u]
    while (1):
        grandq = random.randint(0, q - 1)
        if (grandq == 1 or math.gcd(grandq, q) != 1):
            continue
        f = False
        for prod in partials_q:
            f = f | (pow(grandq, prod, q) == 1)  # modp or modp-1
            if (f):
                break
        if (not f):
            break

    grand = (hrandp * q * mod_inverse(q, p) +
             hrandq * p * mod_inverse(p, q)) % n
    g = pow(grand, 2 * prand * qrand, n)

    priv, pub = {}, {}
    priv['p'], priv['q'], priv['vp'], priv['vq'] = p, q, \
                 vp, vq
    pub['n'], pub['g'], pub['h'], pub['u'], pub['t'] = n, g, \
                  h, u, t

    if (gen_dlut):
        print("Generating dlut....")
        priv['dlut'] = []
        for i in range(pub['u']):
            if (i % 10000 == 0):
                print(i)
            priv['dlut'].append(pow(pub['g'], priv['vp'] * i, priv['p']))
        priv['dlut'] = np.array(priv['dlut'])

    if (save_in_file):
        np.save(os.path.join(save_dir, "priv.npy"), priv)
        np.save(os.path.join(save_dir, "pub.npy"), pub)

    return priv, pub
Example #24
0
def _discrete_log_pollard_rho(n, a, b, order=None, retries=10, rseed=None):
    """
    Pollard's Rho algorithm for computing the discrete logarithm of ``a`` to
    the base ``b`` modulo ``n``.

    It is a randomized algorithm with the same expected running time as
    ``_discrete_log_shanks_steps``, but requires a negligible amount of memory.

    Examples
    ========

    >>> from sympy.ntheory.residue_ntheory import _discrete_log_pollard_rho
    >>> _discrete_log_pollard_rho(227, 3**7, 3)
    7

    See Also
    ========

    discrete_log

    References
    ==========

    .. [1] "Handbook of applied cryptography", Menezes, A. J., Van, O. P. C., &
        Vanstone, S. A. (1997).
    """
    a %= n
    b %= n

    if order is None:
        order = n_order(b, n)
    prng = Random()
    if rseed is not None:
        prng.seed(rseed)

    for i in range(retries):
        aa = prng.randint(1, order - 1)
        ba = prng.randint(1, order - 1)
        xa = pow(b, aa, n) * pow(a, ba, n) % n

        c = xa % 3
        if c == 0:
            xb = a * xa % n
            ab = aa
            bb = (ba + 1) % order
        elif c == 1:
            xb = xa * xa % n
            ab = (aa + aa) % order
            bb = (ba + ba) % order
        else:
            xb = b * xa % n
            ab = (aa + 1) % order
            bb = ba

        for j in range(order):
            c = xa % 3
            if c == 0:
                xa = a * xa % n
                ba = (ba + 1) % order
            elif c == 1:
                xa = xa * xa % n
                aa = (aa + aa) % order
                ba = (ba + ba) % order
            else:
                xa = b * xa % n
                aa = (aa + 1) % order

            c = xb % 3
            if c == 0:
                xb = a * xb % n
                bb = (bb + 1) % order
            elif c == 1:
                xb = xb * xb % n
                ab = (ab + ab) % order
                bb = (bb + bb) % order
            else:
                xb = b * xb % n
                ab = (ab + 1) % order

            c = xb % 3
            if c == 0:
                xb = a * xb % n
                bb = (bb + 1) % order
            elif c == 1:
                xb = xb * xb % n
                ab = (ab + ab) % order
                bb = (bb + bb) % order
            else:
                xb = b * xb % n
                ab = (ab + 1) % order

            if xa == xb:
                r = (ba - bb) % order
                try:
                    e = mod_inverse(r, order) * (ab - aa) % order
                    if (pow(b, e, n) - a) % n == 0:
                        return e
                except ValueError:
                    pass
                break
    raise ValueError("Pollard's Rho failed to find logarithm")
Example #25
0
 def deal_with_increment(self, i: int, inverse: bool = False):
     if not inverse:
         self.pos = (self.pos * i) % self.cards
     else:
         self.pos = (mod_inverse(i, self.cards) * self.pos) % self.cards
Example #26
0
def test_mod_inverse():
    assert mod_inverse(3, 11) == 4
    assert mod_inverse(5, 11) == 9
    assert mod_inverse(21124921, 521512) == 7713
    assert mod_inverse(124215421, 5125) == 2981
    assert mod_inverse(214, 12515) == 1579
    assert mod_inverse(5823991, 3299) == 1442
    assert mod_inverse(123, 44) == 39
    assert mod_inverse(2, 5) == 3
    assert mod_inverse(-2, 5) == -3
    x = Symbol('x')
    assert S(2).invert(x) == S.Half
    raises(TypeError, lambda: mod_inverse(2, x))
    raises(ValueError, lambda: mod_inverse(2, S.Half))
    raises(ValueError, lambda: mod_inverse(2, cos(1)**2 + sin(1)**2))
Example #27
0
 def mod_inverse(n, k):
     return numbers.mod_inverse(k, n)
Example #28
0
def compare(x, y, l):
    # get bits
    y_b = get_bits(y, l)
    # get encrypted bits
    y_enc = []
    for b in y_b:
        y_enc.append(dgk.encrypt(b, pub))
    y_enc = np.array(y_enc)
    # get bits
    x_b = get_bits(x, l)
    # get encrypted bits
    x_enc = []
    for b in x_b:
        x_enc.append(dgk.encrypt(b, pub))
    x_enc = np.array(x_enc)
    # get encryption of 1
    one_enc = dgk.encrypt(1, pub)
    # get [x xor y]
    xxory = []
    for i in range(l):
        if x_b[i] == 0:
            xxory.append(y_enc[i])
        else:
            xxory.append(
                ((one_enc % pub['n']) *
                 (mod_inverse(y_enc[i], pub['n']) % pub['n'])) % pub['n'])
    xxory = np.array(xxory)

    dela = np.random.randint(0, 2)
    s = 1 - 2 * dela
    s_enc = dgk.encrypt(s, pub)

    # precompute xor cubes
    xor3precomp = [1] * l
    i = l - 2
    while (i >= 0):
        xor3precomp[i] = ((pow(xxory[i + 1], 3, pub['n']) % pub['n']) *
                          (xor3precomp[i + 1] % pub['n'])) % pub['n']
        i -= 1
    # compute [c]
    c = []
    for i in range(l):
        temp = ((s_enc % pub['n']) * (x_enc[i] % pub['n']) *
                (mod_inverse(y_enc[i], pub['n'])) % pub['n'] *
                (xor3precomp[i] % pub['n'])) % pub['n']
        r = np.random.randint(1, pub['u'])
        r_dash = random.getrandbits(int(2.5 * pub['t']))
        temp = (pow(temp, r, pub['n']) *
                pow(pub['h'], r_dash, pub['n'])) % pub['n']
        c.append(temp)
    c = np.array(c)
    # shuffle c
    np.random.shuffle(c)

    #-----------------B-------------------
    delb = 0
    for ci in c:
        ci_iszero = dgk.decrypt_iszero(ci, priv)
        if (ci_iszero):
            delb = 1
            break

    #-----------------AB-------------------
    # how to use the values dela delb in an actual algo??
    print("IS x <= y ? ", bool(dela ^ delb))
Example #29
0
def test_mod_inverse():
    assert mod_inverse(3, 11) == 4
    assert mod_inverse(5, 11) == 9
    assert mod_inverse(21124921, 521512) == 7713
    assert mod_inverse(124215421, 5125) == 2981
    assert mod_inverse(214, 12515) == 1579
    assert mod_inverse(5823991, 3299) == 1442
    assert mod_inverse(123, 44) == 39
    assert mod_inverse(2, 5) == 3
    assert mod_inverse(-2, 5) == -3
    x = Symbol('x')
    assert S(2).invert(x) == S.Half
    raises(TypeError, lambda: mod_inverse(2, x))
    raises(ValueError, lambda: mod_inverse(2, S.Half))
    raises(ValueError, lambda: mod_inverse(2, cos(1)**2 + sin(1)**2))
Example #30
0
assert isprime(q)
assert p.bit_length() == num_bits
assert q.bit_length() == num_bits

n = p * q
z = (p - 1) * (q - 1)

e = 65537  # specified encryption exponent
import math
assert math.gcd(e, z) == 1

#
# RSA decryption/private factor
#
from sympy.core.numbers import mod_inverse
d = mod_inverse(e, z)
assert (e * d - 1) % z == 0

#
# Extracting the integer underlying an arbitrary string
#
import sys
# Using p, q, n, z as before
m_str = 'Tøp Secrèt!'
m_bytes = m_str.encode()
m = int.from_bytes(m_bytes, byteorder=sys.byteorder, signed=False)
assert m < n, 'Modulus is too small for message'

#
# RSA encryption and decryption
#
Example #31
0
nsquare_byte = private_key.p.to_bytes(256, 'little')
privatekey_file.write(nsquare_byte)

print('\nprivate key q')
print(private_key.q)
print(hex(private_key.q))
printhex(private_key.q)
nsquare_byte = private_key.q.to_bytes(256, 'little')
privatekey_file.write(nsquare_byte)

print('\nprivate key lamda')
lamda = lcm(private_key.p - 1, private_key.q - 1)
lamda = int(lamda)
print(lamda)
print(hex(lamda))
printhex(lamda)
nsquare_byte = lamda.to_bytes(256, 'little')
privatekey_file.write(nsquare_byte)

print('\nprivate key g_lamda_inv')
g_lamda = (fastExpMod(public_key.g, lamda, public_key.nsquare) -
           1) // public_key.n
g_lamda_inv = mod_inverse(g_lamda, public_key.n)
print(g_lamda_inv)
print(hex(g_lamda_inv))
printhex(g_lamda_inv)
nsquare_byte = g_lamda_inv.to_bytes(256, 'little')
privatekey_file.write(nsquare_byte)

#print(public_key.encrypt(value=3, r_value=3).ciphertext(False))
Example #32
0
        print("CT = ", CT)
        print("PT = ", PT)
    elif choice == 2:
        p, q = [int(x) for x in input("Enter values of p,q: ").split(' ')]
        if (sympy.isprime(p) and sympy.isprime(q)):
            print("p: ", p, "q : ", q)
            n = p * q
            phi_n = (p - 1) * (q - 1)
            e = int(input("\nEnter Value of e: "))
            if (e > phi_n or e < 1):
                print("Value must be 1<e<", phi_n)
            elif (math.gcd(e, phi_n) != 1):
                print("GCD({},{})!=1".format(e, phi_n))
                print("e and (p-1)(q-1) must be coprime")
            else:
                d = mod_inverse(e, phi_n)
                print("Public Key:({},{})".format(e, n))
                print("Private Key:({},{})".format(d, n))
                M = int(input("\nEnter Plaintext: "))
                Y = (M**d) % n
                print("Signed Message (M,Y): ({},{}) ".format(M, Y))
                Z = (Y**e) % n
                print("M:{} Z:{}".format(M, Z))
                if (M == Z):
                    print("Signature Valid")
                else:
                    print("Signature Invalid")
    else:
        break
"""
OUTPUT