示例#1
0
    def test_openssh_gauntlet(self):
        num_runs = 6
        num_enc = num_runs // 3
        for i in range(num_runs):
            dsa = DSA()
            passphrase = None
            if i < num_enc:
                passphrase = Bytes.random(Bytes.random(1).int())

            priv = dsa.export_private_key(encoding=PKIEncoding.OpenSSH,
                                          encryption=b'aes256-ctr',
                                          passphrase=passphrase)
            pub_openssh = dsa.export_public_key(encoding=PKIEncoding.OpenSSH)
            pub_ssh2 = dsa.export_public_key(encoding=PKIEncoding.SSH2)

            new_priv = DSA.import_key(priv, passphrase=passphrase)
            new_pub_openssh = DSA.import_key(pub_openssh)
            new_pub_ssh2 = DSA.import_key(pub_ssh2)

            self.assertEqual(
                (new_priv.p, new_priv.q, new_priv.g, new_priv.x, new_priv.y),
                (dsa.p, dsa.q, dsa.g, dsa.x, dsa.y))
            self.assertEqual((new_pub_openssh.p, new_pub_openssh.q,
                              new_pub_openssh.g, new_pub_openssh.y),
                             (dsa.p, dsa.q, dsa.g, dsa.y))
            self.assertEqual((new_pub_ssh2.p, new_pub_ssh2.q, new_pub_ssh2.g,
                              new_pub_ssh2.y), (dsa.p, dsa.q, dsa.g, dsa.y))
示例#2
0
    def test_crack(self):
        for i in range(5000):
            # Fuzz some variables into existence
            length = max(next_prime(Bytes.random(2).int() % 1000), 5)
            tap_dist = min(next_prime(length // 2), length - 1)

            feed = Bytes.random(2).int() % length
            tap = (feed - tap_dist) % length
            operation = LFG.ADD_OP if i % 2 else LFG.SUB_OP
            increment = ((i % 4) // 2)

            # Set up the LFGs
            lfg = LFG(state=[Bytes.random(8).int() for _ in range(length)],
                      tap=tap,
                      feed=feed,
                      length=length,
                      operation=operation,
                      increment=increment)

            num_samples = length + max(1, Bytes.random(1).int() % 50)

            cracked_lfg = LFG(state=[0],
                              tap=tap,
                              feed=feed,
                              length=length,
                              operation=operation,
                              increment=increment)
            cracked_lfg.crack([lfg.generate() for _ in range(num_samples)])

            # Prove they will always be equivalent by generating a number of values greater than twice the LFG length. This guarantees that 1) the entire state has been modified, and 2) the modified state also produces an equivalent modified state.
            predicted_values = [cracked_lfg.generate() for _ in range(2000)]
            real_values = [lfg.generate() for _ in range(2000)]

            self.assertEqual(predicted_values, real_values)
示例#3
0
    def test_openssh_gauntlet(self):
        num_runs = 6
        num_enc = num_runs // 3
        for i in range(num_runs):
            bits = 128 + (Bytes.random(2).int() % (4096 - 128))
            rsa = RSA(bits)
            passphrase = None
            if i < num_enc:
                passphrase = Bytes.random(Bytes.random(1).int())

            priv = rsa.export_private_key(encoding=PKIEncoding.OpenSSH,
                                          encryption=b'aes256-ctr',
                                          passphrase=passphrase)
            pub_openssh = rsa.export_public_key(encoding=PKIEncoding.OpenSSH)
            pub_ssh2 = rsa.export_public_key(encoding=PKIEncoding.SSH2)

            new_priv = RSA.import_key(priv, passphrase=passphrase)
            new_pub_openssh = RSA.import_key(pub_openssh)
            new_pub_ssh2 = RSA.import_key(pub_ssh2)

            self.assertEqual(
                (new_priv.d, new_priv.e, new_priv.n, new_priv.p, new_priv.q),
                (rsa.d, rsa.e, rsa.n, rsa.p, rsa.q))
            self.assertEqual((new_pub_openssh.e, new_pub_openssh.n),
                             (rsa.e, rsa.n))
            self.assertEqual((new_pub_ssh2.e, new_pub_ssh2.n), (rsa.e, rsa.n))
示例#4
0
    def __init__(self,
                 h: int = 2,
                 p: int = DiffieHellman.MODP_1536,
                 key: bytes = None,
                 exp1: int = None,
                 exp2: int = None,
                 validate: bool = True):
        """
        Parameters:
            h         (int): Generator.
            p         (int): Prime modulus.
            key     (bytes): Secret.
            exp1      (int): First random exponent.
            exp2      (int): Second random exponent.
            validate (bool): Whether or not to validate challenges to prevent exploits.
        """
        self.h = h
        self.p = p
        self.key = Bytes.wrap(key).int() or Bytes.random(16).int()
        self.validate = validate

        # We do this explicitly with None so users can easily set these values to zero :)
        if exp1 is None:
            exp1 = Bytes.random(16).int()

        if exp2 is None:
            exp2 = Bytes.random(16).int()

        self.exp1 = exp1
        self.exp2 = exp2

        self.P_b = None

        self.P = None
        self.Q = None
示例#5
0
    def test_gauntlet(self):
        for block_size in range(8, 32):
            pkcs = PKCS7(block_size)

            for _ in range(1000):
                plaintext = Bytes.random(Bytes.random(1).int() % block_size)
                self.assertEqual(pkcs.unpad(pkcs.pad(plaintext)), plaintext)
示例#6
0
    def test_openssh_gauntlet(self):
        num_runs = 6
        num_enc = num_runs // 3
        curves = [P192, P224, P256, P384, P521]
        for i in range(num_runs):
            curve = random.choice(curves)
            ecdsa = ECDSA(curve.G)
            passphrase = None
            if i < num_enc:
                passphrase = Bytes.random(Bytes.random(1).int())

            priv = ecdsa.export_private_key(encoding=PKIEncoding.OpenSSH,
                                            encryption=b'aes256-ctr',
                                            passphrase=passphrase)
            pub_openssh = ecdsa.export_public_key(encoding=PKIEncoding.OpenSSH)
            pub_ssh2 = ecdsa.export_public_key(encoding=PKIEncoding.SSH2)

            new_priv = ECDSA.import_key(priv, passphrase=passphrase)
            new_pub_openssh = ECDSA.import_key(pub_openssh)
            new_pub_ssh2 = ECDSA.import_key(pub_ssh2)

            self.assertEqual((new_priv.d, new_priv.G, new_priv.Q),
                             (ecdsa.d, ecdsa.G, ecdsa.Q))
            self.assertEqual((new_pub_openssh.G, new_pub_openssh.Q),
                             (ecdsa.G, ecdsa.Q))
            self.assertEqual((new_pub_ssh2.G, new_pub_ssh2.Q),
                             (ecdsa.G, ecdsa.Q))
示例#7
0
 def crossover_func(parents):
     if Bytes.random(1).int() < 32:
         crossover_idx = Bytes.random(1).int() % len(hamlet_excerpt)
         ret = parents[0].state[:crossover_idx] + parents[1].state[
             crossover_idx:]
     else:
         ret = parents[0].state
     return ret
示例#8
0
        def mutation_func(individual):
            if Bytes.random(1).int() < 32:
                mutation_idx = Bytes.random(1).int() % len(hamlet_excerpt)
                mutation = random.choice(valid_chars)
                individual.state = individual.state[:
                                                    mutation_idx] + mutation + individual.state[
                                                        mutation_idx + 1:]

            return individual
示例#9
0
 def _run_tests(self, hash_type, reference_method):
     for i in range(hash_type().block_size // 8):
         for _ in range(100):
             key = Bytes.random(i * 8)
             in_bytes = Bytes.random(i * 32)
             samson_hash = HMAC(key=key, hash_obj=hash_type())
             self.assertEqual(
                 samson_hash.generate(in_bytes),
                 pyhmac.HMAC(key, in_bytes, reference_method).digest())
示例#10
0
    def test_gauntlet(self):
        for _ in range(10):
            bits = max(16, Bytes.random(2).int() >> 4)
            rsa = RSA(bits, e=65537)

            for _ in range(10):
                plaintext = Bytes.random((bits // 8) - 1)
                ciphertext = rsa.encrypt(plaintext)

                self.assertEqual(
                    rsa.decrypt(ciphertext).zfill(len(plaintext)), plaintext)
示例#11
0
    def test_gauntlet(self):
        rij = Rijndael(Bytes(0x0).zfill(32))
        cts = ECBCTS(rij)

        for _ in range(100):
            plaintext = Bytes.random(Bytes.random(1).int() + 17)

            if len(plaintext) < 17:
                plaintext = plaintext.zfill(17)

            ciphertext = cts.encrypt(plaintext)
            self.assertEqual(cts.decrypt(ciphertext), plaintext)
示例#12
0
    def test_correctness(self):
        for _ in range(100):
            seed = Bytes.random(16).int()
            a = Bytes.random(2).int()
            m = Bytes.random(12).int()
            c = Bytes.random(2).int()

            lcg = LCG(X=seed, a=a, c=c, m=m)
            ref_lcg = wiki_lcg(m, a, c, seed).__next__

            self.assertEqual([lcg.generate() for _ in range(10000)],
                             [ref_lcg() for _ in range(10000)])
示例#13
0
    def test_import_enc_gauntlet(self):
        supported_algos = RFC1423_ALGOS.keys()
        for algo in supported_algos:
            for _ in range(10):
                rsa = RSA(512)
                key = Bytes.random(Bytes.random(1).int() + 1)
                enc_pem = rsa.export_private_key(encryption=algo,
                                                 passphrase=key)
                dec_rsa = RSA.import_key(enc_pem, key)

                self.assertEqual((rsa.d, rsa.e, rsa.p, rsa.q),
                                 (dec_rsa.d, dec_rsa.e, dec_rsa.p, dec_rsa.q))
示例#14
0
    def test_import_enc_gauntlet(self):
        supported_algos = RFC1423_ALGOS.keys()
        for algo in supported_algos:
            for _ in range(10):
                dsa = DSA(None)
                key = Bytes.random(Bytes.random(1).int() + 1)
                enc_pem = dsa.export_private_key(encryption=algo,
                                                 passphrase=key)
                dec_dsa = DSA.import_key(enc_pem, key)

                self.assertEqual((dsa.p, dsa.q, dsa.g, dsa.y),
                                 (dec_dsa.p, dec_dsa.q, dec_dsa.g, dec_dsa.y))
示例#15
0
    def test_import_enc_gauntlet(self):
        supported_algos = RFC1423_ALGOS.keys()
        for algo in supported_algos:
            for _ in range(10):
                ecdsa = ECDSA(G=P256.G, hash_obj=None)
                key = Bytes.random(Bytes.random(1).int() + 1)
                enc_pem = ecdsa.export_private_key(encryption=algo,
                                                   passphrase=key)
                dec_ecdsa = ECDSA.import_key(enc_pem, key)

                self.assertEqual((ecdsa.G, ecdsa.d, ecdsa.Q),
                                 (dec_ecdsa.G, dec_ecdsa.d, dec_ecdsa.Q))
示例#16
0
    def encrypt(self, m: int) -> DGHVBit:
        """
        Encrypts a bit `m`.

        Parameters:
            m (int): Number to encrypt.

        Returns:
            DGHVBit: Encrypted bit.
        """
        q = Bytes.random(8).to_int()
        r = Bytes.random(8).to_int() % (self.p // 4)
        return DGHVBit(self.p * q + 2 * r + m)
示例#17
0
    def test_xor(self):
        dghv = DGHV()

        for _ in range(1000):
            a, b = Bytes.random(4).to_int(), Bytes.random(4).to_int()
            a_bin = [int(char) for char in bin(a)[2:].zfill(32)]
            b_bin = [int(char) for char in bin(b)[2:].zfill(32)]

            a_c = [dghv.encrypt(a_int) for a_int in a_bin]
            b_c = [dghv.encrypt(b_int) for b_int in b_bin]

            xord = [a_int + b_int for a_int, b_int in zip(a_c, b_c)]
            assert int(''.join([str(dghv.decrypt(x_int)) for x_int in xord]),
                       2) == (a ^ b)
示例#18
0
    def test_der_encode(self):
        for _ in range(20):
            bits = max(1, Bytes.random(2).int() >> 4)
            rsa = RSA(bits, e=65537)

            should_pem_encode = Bytes.random(1).int() & 1

            der_bytes = rsa.export_private_key(should_pem_encode)
            recovered_rsa = RSA.import_key(der_bytes)

            self.assertEqual(
                (rsa.d, rsa.e, rsa.n, rsa.p, rsa.q),
                (recovered_rsa.d, recovered_rsa.e, recovered_rsa.n,
                 recovered_rsa.p, recovered_rsa.q))
示例#19
0
 def test_whirlpool(self):
     whirlpool = Whirlpool()
     for i in range(9):
         for j in range(100):
             in_bytes = Bytes.random(i * j)
             self.assertEqual(whirlpool.hash(in_bytes),
                              hashlib.new('whirlpool', in_bytes).digest())
示例#20
0
    def receive_initial_challenge(self,
                                  challenge: (int, int),
                                  r: int = None) -> (int, int):
        """
        Receives the Diffie-Hellman challenges and produces the next challenge parameters.

        Parameters:
            challenge ((int, int)): Challenge from peer.
            r                (int): Ephemeral random exponent.
        
        Returns:
            (int, int): P and Q values to send to its peer.
        """
        h_a1, h_a2 = challenge
        if self.validate:
            assert h_a1 != 1
            assert h_a2 != 1

        r = r or Bytes.random(16).int()
        g, R = pow(h_a1, self.exp1, self.p), pow(h_a2, self.exp2, self.p)

        self.P = pow(R, r, self.p)
        self.Q = (pow(self.h, r, self.p) * pow(g, self.key, self.p)) % self.p

        return self.P, self.Q
示例#21
0
    def derive(self, password: bytes, salt: bytes=None, format_output: bool=True) -> Bytes:
        """
        Derives the bcrypt hash.

        Parameters:
            password     (bytes): Password.
            salt         (bytes): Salt.
            format_output (bool): Whether or not to use bcrypt formatting or just output the hash.
        
        Returns:
            Bytes: Derived key/hash.
        """
        if not salt:
            salt = Bytes.random(16)

        salt = Bytes.wrap(salt)
        password = Bytes.wrap(password)
        bf = self.eks_blowfish_setup(salt, password)

        ciphertext = self.constant
        ecb = ECB(bf)

        for _ in range(64):
            ciphertext = ecb.encrypt(ciphertext)

        to_return = ciphertext[:self.output_size]
        if format_output:
            to_return = Bytes(f'${self.version}$'.encode('utf-8') + str(self.cost).zfill(2).encode('utf-8') + b'$' + bcrypt_b64_encode(salt) + bcrypt_b64_encode(ciphertext[:self.output_size]))

        return to_return
示例#22
0
 def test_sha1(self):
     sha1 = SHA1()
     for i in range(9):
         for _ in range(100):
             in_bytes = Bytes.random(i * 32)
             self.assertEqual(sha1.hash(in_bytes),
                              hashlib.sha1(in_bytes).digest())
示例#23
0
 def __init__(self,
              name: str,
              check_bytes: bytes = None,
              n: int = None,
              e: int = None,
              d: int = None,
              q_mod_p: int = None,
              p: int = None,
              q: int = None,
              host: bytes = None):
     """
     Parameters:
         name          (str): Name for bookkeeping purposes.
         check_bytes (bytes): Four random bytes repeated for OpenSSH to check if the decryption worked.
         n             (int): RSA modulus.
         e             (int): RSA public exponent.
         q_mod_p       (int): RSA q^{-1} mod p.
         p             (int): RSA secret prime.
         q             (int): RSA secret prime.
         host        (bytes): Host the key was generated on.
     """
     self.name = name
     self.check_bytes = check_bytes or Bytes.random(4) * 2
     self.n = n
     self.e = e
     self.d = d
     self.q_mod_p = q_mod_p
     self.p = p
     self.q = q
     self.host = host
示例#24
0
    def __init__(self,
                 curve: TwistedEdwardsCurve = EdwardsCurve25519,
                 hash_obj: object = SHA512(),
                 d: int = None,
                 A: TwistedEdwardsPoint = None,
                 a: int = None,
                 h: bytes = None,
                 clamp: bool = True):
        """
        Parameters:
            curve (TwistedEdwardsCurve): Curve used for calculations.
            hash_obj           (object): Instantiated object with compatible hash interface.
            d                     (int): Private key.
            A     (TwistedEdwardsPoint): (Optional) Public point.
            a                     (int): (Optional) Public scalar.
            h                   (bytes): (Optional) Hashed private key.
            clamp                (bool): Whether or not to clamp the public scalar.
        """
        Primitive.__init__(self)

        self.B = curve.B
        self.curve = curve
        self.d = Bytes.wrap(d or max(1,
                                     Bytes.random(hash_obj.digest_size).int()))
        self.H = hash_obj

        self.h = h or hash_obj.hash(self.d)

        a = a or self.h[:self.curve.b // 8].int()
        self.a = curve.clamp_to_curve(a, True) if clamp else a

        self.A = A or self.B * self.a
示例#25
0
    def test_against_random(self):
        for english_val in ENGLISH_VALUES:
            all_values = [Bytes.random(len(english_val))
                          for _ in range(1000)] + [english_val]
            shuffle(all_values)

            self._check_best_sample(english_val, all_values)
示例#26
0
 def test_md5(self):
     md5 = MD5()
     for i in range(9):
         for _ in range(100):
             in_bytes = Bytes.random(i * 32)
             self.assertEqual(md5.hash(in_bytes),
                              hashlib.md5(in_bytes).digest())
示例#27
0
    def test_ripemd160(self):
        ripe = RIPEMD160()

        for i in range(258):
            for _ in range(10):
                test_bytes = Bytes.random(i)
                self.assertEqual(ripe.hash(test_bytes),
                                 hashlib.new('ripemd160', test_bytes).digest())
    def test_gauntlet(self):
        for _ in range(100):
            plaintext = Bytes.random(16)

            rij = Rijndael(Bytes.random(16))
            ocb = OCB2(rij)
            nonce = Bytes.random(16)

            def oracle_func(plaintext, data):
                return ocb.encrypt(nonce, plaintext, data)


            attack = OCBAuthForgeryAttack(ChosenPlaintextOracle(oracle_func))
            tag, ct = attack.execute(plaintext)

            # OCB2 will automatically verify and throw an AssertException if the tag is incorrect
            ocb.decrypt(nonce, (tag, ct), verify=True)
示例#29
0
 def __init__(self, cipher: EncryptionAlg = None, iv: bytes = b'\x00' * 16):
     """
     Parameters:
         cipher (EncryptionAlg): Instantiated encryption algorithm.
         iv             (bytes): Initialization vector.
     """
     self.cmac = CMAC(cipher or Rijndael(Bytes.random(32)))
     self.iv = iv
示例#30
0
 def __init__(self, cipher: EncryptionAlg=None, iv: bytes=b'\x00' * 16):
     """
     Parameters:
         cipher (EncryptionAlg): Instantiated encryption algorithm.
         iv             (bytes): Initialization vector for CBC mode.
     """
     Primitive.__init__(self)
     self.cbc = CBC(cipher or Rijndael(Bytes.random(32)), iv)