示例#1
0
    def test_import_openssh(self):
        for key, passphrase in [
                TEST_OPENSSH0, TEST_OPENSSH1, TEST_OPENSSH2, TEST_OPENSSH3
        ]:
            if passphrase:
                with self.assertRaises(ValueError):
                    DSA.import_key(key)

            dsa = DSA.import_key(key, passphrase=passphrase)
            self.assertEqual(dsa.y, pow(dsa.g, dsa.x, dsa.p))
            self.assertLess(dsa.x, dsa.q)
            self.assertTrue(is_prime(dsa.p))
            self.assertTrue(is_prime(dsa.q))
示例#2
0
    def test_import_openssh(self):
        for key, passphrase in [
                TEST_OPENSSH0, TEST_OPENSSH1, TEST_OPENSSH2, TEST_OPENSSH3
        ]:
            if passphrase:
                with self.assertRaises(ValueError):
                    RSA.import_key(key)

            rsa = RSA.import_key(key, passphrase=passphrase)
            self.assertEqual(rsa.p * rsa.q, rsa.n)
            self.assertEqual(rsa.alt_d,
                             mod_inv(rsa.e, (rsa.p - 1) * (rsa.q - 1)))
            self.assertTrue(is_prime(rsa.p))
            self.assertTrue(is_prime(rsa.q))
示例#3
0
    def __init__(self, p: int, n: int = 1, reducing_poly: Polynomial = None):
        """
        Parameters:
            p                    (int): Prime.
            n                    (int): Exponent.
            reducing_poly (Polynomial): Polynomial to reduce the `PolynomialRing`.
        """
        from samson.math.algebra.rings.integer_ring import ZZ

        assert is_prime(p)
        self.p = p
        self.n = n

        self.internal_ring = ZZ / ZZ(p)

        if not reducing_poly:
            if n == 1:
                reducing_poly = Polynomial([0, 1], self.internal_ring)
            else:
                for c in itertools.product(range(p), repeat=n):
                    poly = Polynomial((1, *c)[::-1], self.internal_ring)
                    if poly.is_irreducible():
                        reducing_poly = poly
                        break

        self.reducing_poly = reducing_poly
        poly_ring = self.reducing_poly.ring
        self.internal_field = poly_ring / poly_ring(reducing_poly)
示例#4
0
    def analyze(n: int) -> 'IntegerAnalysis':
        n_is_prime = is_prime(n)
        byte_aligned = not n % 8

        is_safe_prime = is_sophie_germain_prime(n)
        prime_name = WELL_KNOWN_GROUPS.get(n)

        # Determine bit distribution
        bits = bin(n)[2:]
        bit_distribution = count_items(bits)
        percent_one = bit_distribution['1'] / len(bits)

        uniform_dist = abs(0.50 - percent_one) < 0.05
        factor_mod = n - (1 if n_is_prime else 0)
        small_factors = factor(factor_mod,
                               use_rho=False,
                               use_siqs=False,
                               use_smooth_p=False)
        smoothness_ratio = smoothness(factor_mod, factors=small_factors)

        return IntegerAnalysis(n=n,
                               is_prime=n_is_prime,
                               smoothness_ratio=smoothness_ratio,
                               byte_aligned=byte_aligned,
                               is_safe_prime=is_safe_prime,
                               prime_name=prime_name,
                               percent_one=percent_one,
                               is_uniform=uniform_dist,
                               small_factors=small_factors)
示例#5
0
文件: lcg.py 项目: gcdeshpande/samson
    def check_full_period(self) -> bool:
        """
        Checks whether the LCG will achieve a full period with its current parameters.

        Returns:
            bool: Whether or not it will acheive a full period.
        
        References:
            https://en.wikipedia.org/wiki/Linear_congruential_generator#Period_length
        """
        # Technically, this achieves m-1
        if is_prime(self.m) and self.c == 0 and is_primitive_root(
                self.a, self.m):
            return True

        # Maximially m/4
        elif is_power_of_two(self.m) and self.c == 0:
            return False

        else:
            # 1. m and c are relatively prime
            relatively_prime = gcd(self.m, self.c) == 1

            # 2. a-1 is divisible by all prime factors of m
            factors = [factor for factor in factorint(self.m)]
            divisible_by_all_factors = all([((self.a - 1) % factor) == 0
                                            for factor in factors])

            # 3. a-1 is divisible by 4 if m is divisible by 4
            divisible_by_four = True
            if self.m % 4 == 0:
                divisible_by_four = (self.a - 1) % 4 == 0

            return relatively_prime and divisible_by_all_factors and divisible_by_four
示例#6
0
def generate_ntt_params(v1, v2):
    vec_len = len(v1)
    max_value = max(chain(v1, v2))
    min_mod = max_value**2 * vec_len + 1

    # Find a modulus
    for offset in count(max(1, min_mod + vec_len - 2)):
        modulus = offset * vec_len + 1

        if is_prime(modulus):
            break

    totient = modulus - 1

    # Find a generator
    factors = [f for f, _ in factor(totient).items()]

    for possible_gen in range(1, modulus):
        if pow(possible_gen, totient, modulus) == 1 and all(
            [pow(possible_gen, totient // f, modulus) != 1 for f in factors]):
            gen = possible_gen
            break

    # Find a primitive root
    root = pow(gen, totient // vec_len, modulus)
    return root, modulus
示例#7
0
文件: dsa.py 项目: gcdeshpande/samson
    def __init__(self, hash_obj: object=SHA256(), p: int=None, q: int=None, g: int=None, x: int=None, L: int=2048, N: int=256):
        """
        Parameters:
            hash_obj (object): Instantiated object with compatible hash interface.
            p           (int): (Optional) Prime modulus.
            q           (int): (Optional) Prime modulus.
            g           (int): (Optional) Generator.
            x           (int): (Optional) Private key.
            L           (int): (Optional) Bit length of `p`.
            N           (int): (Optional) Bit length of `q`.
        """
        Primitive.__init__(self)
        # Parameter generation
        # https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf
        if not q:
            q = find_prime(N)

            # Start somewhere in 2**(L-1); ensure it's even
            i = Bytes.random((L-1) // 8).int() // 2 * 2

            # Construct the base as an even multiple of `q`
            base = 2**(L-1) // (2*q) * 2
            while not is_prime((base + i) * q + 1):
                i += 2

            p = (base + i) * q + 1
            assert (p-1) % q == 0

            # Construct `g`
            while True:
                h = Bytes.random(N // 8).int() % (p-1)
                g = pow(h, (p-1) // q, p)

                if h > 1 and h < (p-1) and g > 1:
                    break

        self.p = p
        self.q = q
        self.g = g

        self.x = x or random_int_between(1, self.q)
        self.y = pow(self.g, self.x, self.p)
        self.hash_obj = hash_obj
示例#8
0
def invert_poly(f_poly: Polynomial, R_poly: Polynomial, p: int) -> Polynomial:
    """
    Inverts a polynomial `f_poly` over `R_poly` in GF(p).

    Parameters:
        f_poly (Polynomial): Polynomial to be inverted.
        R_poly (Polynomial): Polynomial to be inverted _over_.
        p             (int): Integer modulus.

    Returns:
        Polynomial: Inverted polynomial.
    """
    power_of_two = is_power_of_two(p)
    if is_prime(p) or power_of_two:
        if power_of_two:
            Z_p = ZZ / ZZ(2)
        else:
            Z_p = ZZ / ZZ(p)

        f_poly_p = Polynomial([(idx, Z_p[coeff])
                               for idx, coeff in f_poly.coeffs], Z_p)
        R_poly_p = Polynomial([(idx, Z_p[coeff])
                               for idx, coeff in R_poly.coeffs], Z_p)

        inv_poly = mod_inv(f_poly_p, R_poly_p)
        inv_poly = Polynomial([(idx, ZZ[int(coeff)])
                               for idx, coeff in inv_poly.coeffs], ZZ)

        if power_of_two:
            for _ in range(int(math.log(p, 2))):
                inv_poly = (2 * inv_poly) - (f_poly * (inv_poly**2))
                inv_poly = (inv_poly % R_poly).trunc(p)

    else:
        raise Exception(
            f"Polynomial not invertible in Z_{p}. NTRU: p and q must be prime or power of two."
        )

    return inv_poly
示例#9
0
 def is_prime(self) -> list:
     return is_prime(self.val)