def our_CRT(y, d, p, q, r):
    """
    Chinese Remainder Theorem as performed with our modular exponentiation and inverse.

    :param y:
    :param d:
    :param p:
    :param q:
    :param r:
    :return: CRT result + computation time
    """
    # time:
    start = time.time()
    # Fermat for computing x_p, x_q, x_r:
    x_p = modular_exponentiation(y % p, d % (p - 1), p)
    x_q = modular_exponentiation(y % q, d % (q - 1), q)
    x_r = modular_exponentiation(y % r, d % (r - 1), r)

    # CRT the school way:
    N = p * q * r
    N1 = N // p
    N2 = N // q
    N3 = N // r

    x1 = sympy.mod_inverse(N1, p)
    x2 = sympy.mod_inverse(N2, q)
    x3 = sympy.mod_inverse(N3, r)

    x = ((x_p * x1 * N1) + (x_q * x2 * N2) + (x_r * x3 * N3)) % N

    # returning CRT result + time
    return x, time.time() - start
Beispiel #2
0
    def __init__(self, bits_modulo=2048, e=2**16 + 1):
        """
        Genera una clau RSA (de 2048 bits i amb exponent públic 2**16+1 per defecte).
        """
        self.publicExponent = e
        self.primeP = sympy.randprime(pow(2, (bits_modulo - 1)),
                                      pow(2, bits_modulo))
        self.primeQ = sympy.randprime(pow(2, (bits_modulo - 1)),
                                      pow(2, bits_modulo))

        while not self.p_and_q_coprimes_with_e(
        ) and self.primeP == self.primeQ:
            self.primeP = sympy.randprime(pow(2, (bits_modulo - 1)),
                                          pow(2, bits_modulo))
            self.primeQ = sympy.randprime(pow(2, (bits_modulo - 1)),
                                          pow(2, bits_modulo))

        self.modulus = self.primeP * self.primeQ
        self.privateExponent = sympy.mod_inverse(
            self.publicExponent, (self.primeP - 1) * (self.primeQ - 1))
        self.privateExponentModulusPhiP = self.privateExponent % (self.primeP -
                                                                  1)
        self.privateExponentModulusPhiQ = self.privateExponent % (self.primeQ -
                                                                  1)
        self.inverseQModulusP = sympy.mod_inverse(self.primeQ, self.primeP)
Beispiel #3
0
def crack_rsa(e, N):
    phi_N = (primefactors(N, False)[1] - 1) * (primefactors(N, False)[2] - 1)
    d = mod_inverse(e, phi_N)
    #validation of cracked private key
    if (mod_inverse(d, phi_N) != e):
        return "ERROR"
    return (d, N)
    def __add__(self, Q):
        x_1, y_1, x_2, y_2 = self.x, self.y, Q.x, Q.y
        if (x_1, y_1) == (x_2, y_2):

            # case where P + P + 0 = 0 (only one point on curve)
            if y_1 == 0:
                return Point(self.curve, x_1, y_1)

            # case where P + P + Q = 0 (two points on curve)
            s = ((3 * pow(x_1, 2) + self.curve.a) /
                 (mod_inverse(2 * y_1, self.mod))) % self.mod
        else:

            # case where P + Q + 0 = 0 (vertical line)
            if x_1 == x_2:
                return Point(self.curve, self.x, self.y)
            # case where P + Q + r = 0 (tree points on curve)

            s = ((y_2 - y_1) / (mod_inverse(x_2 - x_1, self.mod))) % self.mod
        self.x = (pow(s, 2) - x_2 - x_1) % self.mod
        self.y = ((s * (self.x - x_1)) + y_1) % self.mod

        print(self.x, self.y)
        # return for drawing the resulting point
        return Point(self.curve, self.x, -self.y)
def our_CRT(e, d, p, q, y):
    """
    Chinese Remainder Theorem as performed with our modular exponentiation and inverse.

    :param e:
    :param d:
    :param p:
    :param q:
    :param y:
    :return: result + time
    """
    # time:
    start = time.time()

    x_q = modular_exponentiation(y % q, d % (q - 1), q)

    # Hensel:
    x0 = modular_exponentiation(y % p, d % (p - 1), p)
    x1 = (((y - modular_exponentiation(x0, e, p * p)) / p) *
          modular_inverse(e * modular_exponentiation(x0, e - 1, p * p), p)) % p
    x_p2 = int((x1 * p + x0) % (p * p))

    # for CRT:
    # moduli = [p * p, q]
    # residues = [x_p2, x_q]
    # return crt(moduli, residues)[0], time.time() - start

    # CRT:
    N = p * p * q
    N1 = q
    N2 = p * p
    x1 = sympy.mod_inverse(N1, p * p)
    x2 = sympy.mod_inverse(N2, q)
    x = ((x_p2 * x1 * N1) + (x_q * x2 * N2)) % N
    return x, time.time() - start
Beispiel #6
0
def summ(x1, y1, x2, y2, fp):
    t1 = y2 - y1
    t2 = x2 - x1

    x3 = ((t1 * mod_inverse(t2, fp) % fp)**2 - (x1 + x2)) % fp
    y3 = (-y1 + (t1 * mod_inverse(t2, fp) % fp) * (x1 - x3)) % fp
    return x3, y3
Beispiel #7
0
def compute_free_coef(z, a, prime, x=0):
    product_of_inverses = []
    inverses = np.zeros(int((prime + 1) / 2))
    free_coef = 0
    check_product = []
    for i in a:
        product_of_inverses = []
        # check_product = []
        for j in a:
            if j != i:
                to_inverse = (i - j) % prime
                if to_inverse >= int((prime + 1) / 2):
                    if inverses[-to_inverse % prime] == 0:
                        # print("compute inverse")
                        inverses[-to_inverse % prime] = sympy.mod_inverse(
                            -to_inverse % prime, prime)
                    product_of_inverses.append(
                        int((x - j) * (-inverses[-to_inverse % prime]) %
                            prime))
                else:
                    if inverses[to_inverse] == 0:
                        # print("compute inverse")
                        inverses[to_inverse] = sympy.mod_inverse(
                            to_inverse, prime)
                    product_of_inverses.append(
                        int((x - j) * inverses[to_inverse] % prime))
                check_product.append((x - j) * sympy.mod_inverse(
                    (i - j), prime) % prime)
        # print(inverses)
        # print("check:", check_product)
        # print("product:", product_of_inverses)
        free_coef += z[i - 1] * np.product(product_of_inverses)
        # print(free_coef % prime)
    # print(check_product)
    return free_coef % prime
Beispiel #8
0
def crack_schnorr(s1, s2, w_, open):
    p, q, g, y = open
    t1 = s2 * mod_inverse(s2 - w_ * s1, q)
    t2 = s1 * mod_inverse(s2 - w_ * s1, q)
    print(g, t1, y, t2)
    g_ = (naive_mod_pow(g, t1, p) * naive_mod_pow(y, t2, p)) % p
    y_ = mod_inverse(naive_mod_pow(g_, w_, p), p)
    return p, q, g_, y_
Beispiel #9
0
def summodinak(x1, y1, a, fp):
    a = a % fp
    t1 = 3 * x1**2 + a
    t2 = 2 * y1

    x3 = (t1 * mod_inverse(t2, fp) % fp)**2 - 2 * x1
    y3 = -y1 + (t1 * mod_inverse(t2, fp) % fp) * (x1 - x3)
    return x3 % fp, y3 % fp
Beispiel #10
0
 def __eq__(self, other):
     """Two points are equal if X/Z of both points are equal
     """
     from sympy import mod_inverse
     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
def calculate_slope(x1, y1, x2, y2, prime, a):
    assert x1 == x1 % prime
    assert y1 == y1 % prime
    assert x2 == x2 % prime
    assert y2 == y2 % prime
    return (mod_inverse(2 * y1, prime) * (3 * x1**2 + a) % prime if
            (x1,
             y1) == (x2,
                     y2) else mod_inverse(x2 - x1, prime) * (y2 - y1) % prime)
Beispiel #12
0
def checaInv(l, n):
    inv = True
    try:
        mod_inverse(l, n)
    # Manejamos la excepción que lanza el mod_inverse cuando no existe
    # el inverso modular para aprovecharlo en la bandera y regresar False
    except:
        inv = False
    return inv
Beispiel #13
0
def garner(y, d, p, q, r):
    start = time.time()
    mp = pow(y % p, d % (p - 1), p)
    mq = pow(y % q, d % (q - 1), q)
    mr = pow(y % r, d % (r - 1), r)
    x = mp
    alpha = (((mq - x) % q) * sympy.mod_inverse(mp, q)) % q
    x += alpha * mp
    alpha = (((mr - x) % r) * sympy.mod_inverse(mp * mq, r)) % r
    x += alpha * mp * mq
    end = time.time() - start
    return x, end
def Garner(a_, b_, c_, ar_, br_, cr_):
    a = int(a_)
    b = int(b_)
    c = int(c_)
    ar = int(ar_)
    br = int(br_)
    cr = int(cr_)
    x = ar + (br - ar) * sym.mod_inverse(a, b) % b * a
    x = x + (cr - x % c) * sym.mod_inverse(a, c) % c * sym.mod_inverse(
        b, c) % c * a * b
    #x %= a*b*c #a<b<cのときこの処理は必要ない
    return x
Beispiel #15
0
def reduce(MOD, NITER, POS):
    difference, initial = 1, 0    
    for line in data:
        command, *_, N = line.split()
        if N == 'stack':
            difference *= -1
            initial += difference
        elif command == 'cut':
                initial += int(N) * difference
        else:
            difference *= mod_inverse(int(N), MOD) # ...or just use Fermat's little theorem.      

    initial *= mod_inverse(1 - difference, MOD) # Geometric series
    difference = pow(difference, NITER, MOD)
    return ((POS - initial) * difference + initial) % MOD
def elliptic_curve_sum(e_curve, p1, p2):
    lam = 0  # lambda - slope of the line through two points
    if p1 == p2:
        # p1 and p2 are the same point
        lam = (3 * pow(p1.x, 2) + e_curve.a) * sympy.mod_inverse(
            2 * p1.y, e_curve.p)
    else:
        # p1 and p2 are different
        lam = (p2.y - p1.y) * sympy.mod_inverse(p2.x - p1.x, e_curve.p)
    # finding resulting point
    x_res = (pow(lam, 2) - p1.x - p2.x) % e_curve.p
    y_res = (lam * (p1.x - x_res) - p1.y) % e_curve.p
    # returning resulting point
    res_point = Point(x_res, y_res)
    return res_point
Beispiel #17
0
def reduction_sparse_matrix(boundary_matrix, mod):
    """Return reduced boundary matrix in column echelon form, basis elements for each column and indices of all
    zero columns. All operations are done modulo mod.

    Parameters:
    boundary matrix -- as in the function sparse_boundary_matrix
    mod -- positive integer

    Return:
    reduced_matrix -- reduced matrix in echelon form in the sparse format, given as a list of pairs which are initially
                      all equal to ([], None)
                      reduced_matrix[i] = (col, j) iff j-th column has lowest nonzero entry in i-th row
                      column col is given in ordered sparse format with lowest entry equal to 1
    zero_columns -- a list of indices of zero columns in reduced matrix
    columns -- a list of dictionaries, columns[i] represents the basis element (chain) for the i-th column
               columns[i] is a dictionary: key = indeks of a simplex in the total ordering of the filtration
                                           value = coefficient (only nonzero) for the simplex in the chain
    """
    m = len(boundary_matrix)
    reduced_matrix = [([], None) for _ in range(m)]

#    print_sparse(boundary_matrix)
#    print('\n')

    zero_columns = []
    columns = [{i: 1} for i in range(m)]  # We start with the standard basis.
    
    for j in range(m):
        column = boundary_matrix[j]
        while len(column) > 0 and len(reduced_matrix[column[0][0]][0]) > 0:  # Reduce the column.
            add_chains(columns[j], columns[reduced_matrix[column[0][0]][1]], - column[0][1], mod)
            column = add_columns(column, reduced_matrix[column[0][0]][0], - column[0][1], mod)

        if len(column) > 0:  # New pivot column.
            mult_column(column, sp.mod_inverse(column[0][1], mod), mod)
            mult_chain(columns[j], sp.mod_inverse(column[0][1], mod), mod)
            reduced_matrix[column[0][0]] = (column, j)
        else:  # New zero column.
            zero_columns.append(j)

#        test_matrix = reduced_matrix[:j+1] + boundary_matrix[j+1:]
#        print_sparse(test_matrix)
#        print('\n')

#    print('boundary_matrix')
#    print_sparse1(reduced_matrix)

    return reduced_matrix, zero_columns, columns
def brute_force_attack(n, e, encrypted_data):
    prime_factors = []

    i = 2

    while (i * i <= n):
        if n % i == 0:
            prime_factors = [i, n / i]
            break
        i += 1


    p = prime_factors[0]
    q = prime_factors[1]
    phi = (p - 1) * (q - 1)

    # gcd = GCDExtended(e, phi, d, k)
    # print(d, k)

    # Private key
    d = mod_inverse(e, phi)

    # Decrypted data.
    decrypted_data = "".join([chr(pow(char, d, n)) for char in encrypted_data])
    return decrypted_data
Beispiel #19
0
def multiprime_RSA(iterations=10):
    average_time = 0
    for iteration in range(iterations):
        print("Iteration:", iteration)
        p, q, r = generate_pqr_primes()
        e = pow(2, 16) + 1
        n = p * q * r
        phi_n = (p - 1) * (q - 1) * (r - 1)
        condition = gcd(e, phi_n)
        while condition != 1:
            p, q, r = generate_pqr_primes()
            n = p * q * r
            phi_n = (p - 1) * (q - 1) * (r - 1)
            condition(e, phi_n)
        d = sympy.mod_inverse(e, phi_n)
        y = encrypt_message("message.txt", n, e)
        # print("p:", p)
        # print("q:", q)
        # print("r:", r)
        # print("e:", e)
        # print("d:", d)
        # print("m:", int.from_bytes(get_message(path="message.txt"), byteorder=sys.byteorder))
        # print("y:", y)
        x_decrypt, time_decrypt = decrypt(y, d, n)
        x_garner, time_garner = garner(y, d, p, q, r)
        print("\ty decrypted with python library:", x_decrypt)
        print("\ty decrypted with Garner:", x_garner)
        print("\tgarner vs python function time:", time_decrypt/time_garner)
        average_time += time_decrypt/time_garner
    print(average_time/10)
Beispiel #20
0
def pollig_hellman(base, result, field):
    """
    Function finds a logarithm from given result with given base
    using Pollig-Hellman's algorythm.\n
    Algorythm works on cyclic multiplicative groups with simple fields and compound fields.\n
    :param int base: base of a logarithm\n
    :param int result: result of a logarithm\n
    :param int field: field of a cyclic multiplicative group\n

    """

    rng = find_representation(field)[0]
    ftrs = []
    rslt = int()
    if pow(result, (field - 1) // 2, field) == 1:
        ftrs.append(0)
    else:
        ftrs.append(1)
    for dgr in range(1, rng):
        dg = int()
        index = int()
        for ftr in ftrs:
            dg += ftr * (2**index)
            index += 1
        z = (result * pow(mod_inverse(base, field), dg, field)) % field
        m = ((field - 1) // pow(2, dgr + 1, field)) % field
        if pow(z, m, field) == 1:
            ftrs.append(0)
        else:
            ftrs.append(1)
    rslt += ftrs[0]
    for ftr in range(1, len(ftrs)):
        rslt += (ftrs[ftr] * pow(2, ftr, field)) % field
    return rslt
Beispiel #21
0
def test_idiv(x, y):
    xs, ys = Scalar(x), Scalar(y)
    x = x * sympy.mod_inverse(y, GROUP_ORDER)
    xs /= ys
    x %= GROUP_ORDER
    assert int(xs) == x
    assert int(ys) == y
Beispiel #22
0
def mod(x, modulus):
    numer, denom = x.as_numer_denom()
    try:
        return numer * sympy.mod_inverse(denom, modulus) % modulus
    except:
        print('Error: Unable to apply modulus to matrix')
        exit()
Beispiel #23
0
def GenSign(file):
    signeble_file = open(file, "rb")
    sing_file = open(file + "_sign.dat", 'wb')
    readFile = signeble_file.read()
    sha1Hash = hashlib.sha1(readFile)
    hash_int = int(sha1Hash.hexdigest(), 16)
    k = random.randrange(r)
    while math.gcd(k, r) != 1:
        k = random.randrange(r)
    w = pow(g, k, p)
    s = ((hash_int - x * w) * mod_inverse(k, r)) % (r)

    sign = el_gamal_sign_file.encode(
        'ElGamalSignFile',
        dict(keyset={
            'key':
            dict(algid=b'\x80\x06\x02\x00',
                 test='testSign',
                 keydata={'b': b},
                 param={
                     'prime': p,
                     'r': r,
                     'generator': g
                 },
                 ciphertext=dict(w=w, s=s))
        },
             last={}))
    sing_file.write(sign)
    sing_file.close()
    print("sign generated")
    return file + "_sign.dat"
Beispiel #24
0
def gen_keys(_p: int, _q: int) -> tuple:
    """Generating private and public keys

    :param _p: first prime number
    :param _q: second prime number
    :return: the public and private key pairs
    """
    # modulus for public and private keys
    n = _p * _q

    # totient
    # see https://simple.wikipedia.org/wiki/Euler's_totient_function
    phi = (_p - 1) * (_q - 1)

    # picking e > 1 corpime to phi
    # see https://simple.wikipedia.org/wiki/Coprime
    e = secrets.randbelow(phi) + 1
    while math.gcd(e, phi) != 1:
        e = secrets.randbelow(phi) + 1

    # evaluate d using Extended Euclidean algorithm
    # see: https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm
    d = sympy.mod_inverse(e, phi)

    # (e, n) -> public key pair
    # (d, n) -> private key pair
    return (e, n), (d, n)
Beispiel #25
0
def lagrange_coefficient(i: int, ids: List[int]) -> int:
    result = 1
    for j in ids:
        if i != j:
            result *= j * sympy.mod_inverse((j - i) % CURVE_ORDER, CURVE_ORDER)
            result %= CURVE_ORDER
    return result
Beispiel #26
0
 def __truediv__(self, other):
     if (not isinstance(other, Zm)):
         return NotImplemented
     elif (self.m != other.m):
         return NotImplemented
     else:
         return Zm(self.data * mod_inverse(other.data, other.m), self.m)
Beispiel #27
0
def get_inverse(key_matrix, n):
	inv_det = sympy.mod_inverse((int(round(numpy.linalg.det(key_matrix)%26))), 26)


	if n == 2:
		adj = numpy.zeros(shape=(n, n))
		adj[0][0] = key_matrix[1][1]
		adj[1][1] = key_matrix[0][0]
		adj[0][1] = (key_matrix[0][1])*-1
		adj[1][0] = (key_matrix[1][0])*-1
		inv_key_matrix = numpy.dot(inv_det, adj)
		return inv_key_matrix

	else:
		adj = numpy.zeros(shape=(n, n))
		flip = True
		for row in range(3):
			for col in range(3):
				tmp  = numpy.delete(key_matrix, row, axis=0)
				tmp = numpy.delete(tmp, col, axis=1)
				det = int(round(numpy.linalg.det(tmp)))%26
				if not flip:
					det = (det*-1)%26
				adj[col][row] = det
				flip = not flip

		inv_key_matrix = numpy.dot(inv_det, adj)%26
		return inv_key_matrix
Beispiel #28
0
def reduce_vect(top_list, vect, mod):
    """Return the reduced vector and its coefficients with respect to the basis in top_list, working modulo mod.

    Parameters:
    top_list -- a list of basis elements as returned in the function complete_basis
    vect -- a vector to reduce against the basis in top_list

    Return:
    vect -- reduced form of the vector
    top -- top nonzero index in vect (reduced form), if vect reduces to the zero vector then top is None
    coeffs -- a dictionary: key = index of basis vector in top_list
                            value = coefficient at this basis vector when expanding vect in terms of top_list
    """
    vect = vect.copy()
    top = None
    coeffs = dict()
    n = len(vect)
    for i in range(n):
        if (vect[i] % mod) == 0:
            continue

        if top_list[i][1] is not None:
            base = top_list[i][0]
            inv = sp.mod_inverse(base[i], mod)
            coeff = (inv * vect[i]) % mod
            coeffs[i] = coeff
            for j in range(i, n):
                vect[j] = (vect[j] - coeff * base[j]) % mod
        else:
            top = i
            break

    return vect, top, coeffs
 def verify(self, id, TR, TRV, Pverification, hashCombination):
     # Pverification is prover's verifications
     if id > 20:  # firstly, verify id
         hex_as_int = int(hashCombination, 16)  # convert to decimal
         hex_as_binary = bin(hex_as_int)  # convert to binary form
         for i in range(self.x):
             # the reason why I used binary_string[i+2] is because python shows 0b at the beginning of a binary
             # number and it violate the randomness for choosing bit so I start the loop by add 2 to it.
             if hex_as_binary[i+2] == '0':
                 #  we take it and calculate it to the power of e mod n so that it would equal to ---
                 self.verification[i] = (Pverification[i] ** self.Pkey[0]) % self.Pkey[1]
             else:
                 md5 = hashlib.md5()
                 c = str(id) + str(TR) + str(TRV)
                 md5.update(c.encode('utf-8'))
                 hash = int(md5.hexdigest(), 16)
                 modular_inverse = sympy.mod_inverse(hash, self.Pkey[1])
                 self.verification[i] = ((Pverification[i] ** self.Pkey[0]) * modular_inverse) % self.Pkey[1]
         newCombination = str(id) + str(TR) + str(TRV)
         for i in range(self.x):
             newCombination += str(self.verification[i])
         md5 = hashlib.md5()
         md5.update(newCombination.encode('utf-8'))
         newhashCombination = md5.hexdigest()
         print("Hash combination from verifier: ", newhashCombination)
         if newhashCombination == hashCombination:
             return True
         else:
             return False
Beispiel #30
0
 def decrypt_message(self):
     factors = self.__find_prime_factors(self.__n_coef)
     if len(factors) != 2:
         raise ValueError('The N coefficient does not have two factors')
     phi = self.__calc_eulers_phi_for_primes(factors[0], factors[1])
     d_coef = sympy.mod_inverse(self.__e_coef, phi)
     return self.__rsa_decrypt(d_coef)