예제 #1
0
def _get_generator(p, task_monitor=None):
    """
        Returns the generator of the Z_{p}^{*} cyclic group.
        
        We take random numbers in Z_{p}^{*} = [0, ..., p - 1], until one of  
        them is a generator for the group. This function assumes that p is a 
        safe prime (p = 2q + 1 with both p and q prime).
        
        See the documentation for _is_generator(p, g) for more information 
        about testing whether a number is a generator of Z_{p}^{*}.
        
        Arguments:
            p::long    -- A safe prime.
            task_monitor::TaskMonitor    -- A task monitor for the process.
        
        Returns:
            g::long    -- A generator of Z_{p}^{*}
        """
    random = StrongRandom()
    candidate = random.randint(1, p - 1)
    if (task_monitor != None): task_monitor.tick()

    while (not _is_generator(p, candidate)):
        candidate = random.randint(1, p - 1)
        if (task_monitor != None): task_monitor.tick()

    if (params.DEBUG):
        assert pow(candidate, p - 1, p) == 1, \
               "generator^{p-1} != 1 mod p (!) see method's " \
               "algorithm explanation."

    return candidate  # this is the generator
    def get_challenge(self):
        '''
        Generate a QR2Auth challenge.
        A QR2Auth challenge consists of 128 random bits generated by PyCrypto
        with StrongRandom.
        These random bits are hashed with SHA512. This hash value represents
        the challenge.

        :return: A tuple containing the QR2Auth challenge as well as the range
                 of the OTP in the response hash value.
        :rtype: tuple
        '''
        random_pool = StrongRandom()
        nonce = random_pool.getrandbits(128)
        nonce_hash = SHA512.new(str(nonce)).hexdigest()
        self.__start = int(random_pool.randint(0, 128))
        '''
        Start and end of the range must be between 0 and the length of the hash
        We use Sha512, so in this case start and end must be between
        0 and 128
        '''
        self.__end = self.__start + self.__otp_length
        if self.__end > len(nonce_hash):
            self.__end = self.__end - len(nonce_hash)
        self.__challenge = nonce_hash
        return self.__challenge, self.__start, self.__end
def _get_generator(p, task_monitor=None):
        """
        Returns the generator of the Z_{p}^{*} cyclic group.
        
        We take random numbers in Z_{p}^{*} = [0, ..., p - 1], until one of  
        them is a generator for the group. This function assumes that p is a 
        safe prime (p = 2q + 1 with both p and q prime).
        
        See the documentation for _is_generator(p, g) for more information 
        about testing whether a number is a generator of Z_{p}^{*}.
        
        Arguments:
            p::long    -- A safe prime.
            task_monitor::TaskMonitor    -- A task monitor for the process.
        
        Returns:
            g::long    -- A generator of Z_{p}^{*}
        """        
        random = StrongRandom()
        candidate = random.randint(1, p - 1)
        if(task_monitor != None): task_monitor.tick()
        
        while(not _is_generator(p, candidate)):
            candidate = random.randint(1, p - 1)
            if(task_monitor != None): task_monitor.tick()
        
        if(params.DEBUG):
            assert pow(candidate, p - 1, p) == 1, \
                   "generator^{p-1} != 1 mod p (!) see method's " \
                   "algorithm explanation."
        
        return candidate # this is the generator
예제 #4
0
def generate_password(pwd_length,
                      symbols=string.ascii_letters + string.digits +
                      string.digits):
    from Crypto.Random.random import StrongRandom

    ret = ''
    rnd = StrongRandom()
    for i in range(pwd_length):
        ret += rnd.choice(symbols)

    return ret
예제 #5
0
 def __init__(self, cryptosystem):
     """
     Generates a new key pair for the given EGCryptoSystem
     """
     p = cryptosystem.get_prime()
     random = StrongRandom()
     
     inner_private_key = random.randint(1, p - 2)
     
     self.private_key = PrivateKey(cryptosystem, inner_private_key)
     self.public_key = self.private_key.public_key
예제 #6
0
    def __init__(self, cryptosystem):
        """
        Generates a new key pair for the given EGCryptoSystem
        """
        p = cryptosystem.get_prime()
        random = StrongRandom()

        inner_private_key = random.randint(1, p - 2)

        self.private_key = PrivateKey(cryptosystem, inner_private_key)
        self.public_key = self.private_key.public_key
예제 #7
0
    def computeFinalPermutation(output_addresses, checksum):
        # Compute hex presentation of checksum
        seed = checksum.decode('hex')
        """ Create a PRNG based on Crypto.random.random, but with seedable input
            (instead of /dev/urandom). """
        prng_input = SeedablePrngGenerator()
        prng_input.reseed(seed)
        log.debug('Seed: ' + seed.encode('hex'))
        prng = StrongRandom(randfunc=prng_input.pseudo_random_data)

        prng.shuffle(output_addresses)
        return output_addresses
예제 #8
0
    def sign(self, msg_hash):
        """Produce the DSS signature of a message.

        :Parameters:
          msg_hash : hash object
            The hash that was carried out over the message.
            The object belongs to the `Crypto.Hash` package.

            Under mode *'fips-186-3'*, the hash must be a FIPS
            approved secure hash (SHA-1 or a member of the SHA-2 family).

        :Return: The signature encoded as a byte string.
        :Raise ValueError:
            If the hash algorithm is incompatible to the DSA key.
        :Raise TypeError:
            If the DSA key has no private half.
        """

        # Generate the nonce k (critical!)
        if self._deterministic:
            nonce = self._compute_nonce(msg_hash)
        else:
            if self._n > msg_hash.digest_size * 8:
                raise ValueError("Hash is not long enough")

            if not msg_hash.name.upper().startswith("SHA"):
                raise ValueError("Hash %s does not belong to SHS" %
                                 msg_hash.name)

            rng = StrongRandom(randfunc=self._randfunc)
            nonce = rng.randint(1, self._key.q - 1)

        # Perform signature using the raw API
        z = bytes_to_long(msg_hash.digest()[:self._n])
        sig_pair = self._key._sign(z, nonce)

        # Encode the signature into a single byte string
        if self._encoding == 'binary':
            output = b("").join([long_to_bytes(x, self._n) for x in sig_pair])
        else:
            # Dss-sig  ::=  SEQUENCE  {
            #               r       OCTET STRING,
            #               s       OCTET STRING
            # }
            der_seq = DerSequence(sig_pair)
            output = der_seq.encode()

        return output
예제 #9
0
    def sign(self, msg_hash):
        """Produce the DSS signature of a message.

        :Parameters:
          msg_hash : hash object
            The hash that was carried out over the message.
            The object belongs to the `Crypto.Hash` package.

            Under mode *'fips-186-3'*, the hash must be a FIPS
            approved secure hash (SHA-1 or a member of the SHA-2 family).

        :Return: The signature encoded as a byte string.
        :Raise ValueError:
            If the hash algorithm is incompatible to the DSA key.
        :Raise TypeError:
            If the DSA key has no private half.
        """

        # Generate the nonce k (critical!)
        if self._deterministic:
            nonce = self._compute_nonce(msg_hash)
        else:
            if self._n > msg_hash.digest_size * 8:
                raise ValueError("Hash is not long enough")

            if not hash_is_shs(msg_hash):
                raise ValueError("Hash does not belong to SHS")

            rng = StrongRandom(randfunc=self._randfunc)
            nonce = rng.randint(1, self._key.q - 1)

        # Perform signature using the raw API
        z = bytes_to_long(msg_hash.digest()[:self._n])
        sig_pair = self._key._sign(z, nonce)

        # Encode the signature into a single byte string
        if self._encoding == 'binary':
            output = b("").join([long_to_bytes(x, self._n)
                                 for x in sig_pair])
        else:
            # Dss-sig  ::=  SEQUENCE  {
            #               r       OCTET STRING,
            #               s       OCTET STRING
            # }
            der_seq = DerSequence(sig_pair)
            output = der_seq.encode()

        return output
예제 #10
0
파일: rsa.py 프로젝트: zzmjohn/tribler
def rsa_compatible(n, phi):
    phi = long(phi)
    while True:
        e = StrongRandom().randint(1, phi - 1)
        if GCD(e, phi) == 1:
            break
    return RSAKey(mpz(n), mpz(e), None, None, None, 1024)
    def keygen(self):
        '''
        Generate the secret key for QR2Auth aka shared secret.
        A QR2Auth secret key consists of 256 random bits generated by PyCrypto
        with StrongRandom.
        The random bits are hashed with SHA512. This hash value
        represents the secret key aka. shared secret.

        :return: A QRtoAuth shared secret.
        :rtype: str
        '''
        random_pool = StrongRandom()
        key_seed = random_pool.getrandbits(256)
        key = SHA512.new(str(key_seed))
        self.__shared_secret = key.hexdigest()
        return self.__shared_secret
예제 #12
0
    def new_random_polynomial(cls, modulus, degree):
        """
		Construct a new polynomial of the given degree with random coefficients.
		
		Arguments:
			modulus::long	-- All arithmetic for this polynomial will be 
							   performed with this modulus. 
							   That is, in the Z_{modulus} multiplicative group.
			degree::int		-- Degree of the new polynomial.
 		"""
        coefficients = []
        random = StrongRandom()
        for i in range(0, degree + 1):
            coeff = random.randint(1, modulus - 1)
            coefficients.append(coeff)

        return cls(modulus, coefficients)
예제 #13
0
	def new_random_polynomial(cls, modulus, degree):
		"""
		Construct a new polynomial of the given degree with random coefficients.
		
		Arguments:
			modulus::long	-- All arithmetic for this polynomial will be 
							   performed with this modulus. 
							   That is, in the Z_{modulus} multiplicative group.
			degree::int		-- Degree of the new polynomial.
 		"""
		coefficients = []
		random = StrongRandom()
		for i in range(0, degree + 1):
			coeff =  random.randint(1, modulus - 1)
			coefficients.append(coeff)
		
		return cls(modulus, coefficients)
예제 #14
0
 def obtain_splittings_and_schedules(input_peers, split_amount,
                                     mixing_window_mins, seed):
     prng_gen = SeedablePrngGenerator()
     prng_gen.reseed(seed)
     prng = StrongRandom(randfunc=prng_gen.pseudo_random_data)
     for input_peer in input_peers:
         input_peer['split'] = splitMixingAmount(split_amount, prng)
         input_peer['schedule'] = defineStreamingSchedule(
             len(input_peer['split']), mixing_window_mins, prng)
     return
예제 #15
0
    def new(cls, public_key, length):
        """
        Generate a new re-encryption information object with the given length.

        This constructs {length} blocks of random ciphertext re-encryption
        information, which can be applied to a given ciphertext in order to
        produce a re-encrypted ciphertext.

        Arguments:
            public_key::PublicKey-- The public key to be used for re-encryption.
                                   This must be the same public key that was
                                   used to encrypt the original ciphertext.
            length::int -- Number of blocks of re-encryption information.

        Returns:
            reencryption_info::CiphertextReencryptionInfo   --
                A new CiphertextReencryptionInfo object containing length
                random blocks or re-encryption information.
        """
        random = StrongRandom()

        # Get p and g
        prime = public_key.cryptosystem.get_prime()
        generator = public_key.cryptosystem.get_generator()

        # Create a new empty CiphertextReencryptionInfo object
        reencryption_info = CiphertextReencryptionInfo(public_key)

        # Add (length) random re-encryption information blocks
        for i in range(0, length):

            # Select a random integer r, 1 <= r <= p − 2
            r = random.randint(1, prime - 2)

            # store block (g^{r}, y^{r})
            gr = pow(generator, r, prime)
            yr = pow(public_key._key, r, prime)
            reencryption_info.add_block(gr, yr)

        assert (reencryption_info.get_length() == length)

        return reencryption_info
예제 #16
0
class CryptoHelper():
    def __init__(self):
        self.rnd = StrongRandom()

    def generate_verifier_code(self):
        mapped = map(lambda x: self.rnd.getrandbits(8), range(32))
        encoded = b64encode(bytes(mapped))
        verifier = encoded.decode().replace("=", "")
        hash = SHA256Hash.new(self)
        hash.update(verifier.encode("utf-8"))
        digest = b64encode(hash.digest())
        challenge = digest.decode().replace("=", "")
        return {"verifier": verifier, "challenge": challenge}
예제 #17
0
    def new(cls, collection):
        """
        Generate a new mapping compatible with the given collection.

        This method produces a new CiphertextCollectionMapping object that maps
        the given collection into a randomly shuffled collection. To obtain
        said shuffled collection, simply call the apply method of the returned
        mapping, passing once again the collection as an argument.

        The reason this method takes the collection to be shuffled as an
        argument is to ensure that the resulting CiphertextCollectionMapping is
        compatible with said collection. This includes: providing a re-ordering
        and re-encryption for the right number of elements of the right size,
        as well as using the same public key for re-encryption as the one used
        to encrypt the elements of the original collection.

        Arguments:
            collection::CiphertextCollection -- The collection for which we
                                                wish to generate a new mapping.

        Returns:
            mapping::CiphertextCollectionMapping --
                A mapping from collection to a randomly shuffled new collection.
        """
        # Get the public key and length of the collection
        public_key = collection.public_key
        length = collection.get_length()

        # Create an empty mapping
        mapping = CiphertextCollectionMapping()

        # Generate a list of all collection element indexes
        for i in range(0, length):
            mapping._reordering.append(i)

        # Randomly permute those indexes to generate a reordering
        random = StrongRandom()
        ### random.shuffle(self._reordering) is broken upstream, workaround:
        _random_shuffle_in_place(random, mapping._reordering)

        # Generate a random re-encryption for each ciphertext in the collection
        for ciphertext in collection:
            ciphertext_len = ciphertext.get_length()
            reencryption = \
                CiphertextReencryptionInfo.new(public_key, ciphertext_len)
            mapping._reencryptions.append(reencryption)

        # Return the generated mapping
        return mapping
예제 #18
0
파일: ssh-sign.py 프로젝트: unhaltable/txti
	def encrypt(self, path):
		if self.pubfile == '':
			error('No valid RSA public keyfile for encryption.')

		r = StrongRandom()
		digest = MD5.new()
		digest.update(str(r.getrandbits(256)))
		aes = AES.new(digest.hexdigest(), AES.MODE_CFB)

		try:
			fin = open(path, 'rb')
			fout = excl_open(path + '.ssh-aescfb', 0600)

			fout.write(self.pubkey.encrypt(digest.hexdigest(), '')[0])
			buf = ' '
			while buf != '':
				buf = fin.read(4096)
				fout.write(aes.encrypt(buf))
		except:
			error('Unable to open source/target file for encryption.')

		fin.close()
		fout.close()
		return True
예제 #19
0
def pallier_encrypt(key, element):
    assert element in [0, 1], element

    _n = long(key.n)
    while True:
        r = StrongRandom().randint(1, _n)
        if GCD(r, _n) == 1: break
    r = mpz(r)

    #key_g < n2, so no need for modulo
    t1 = key.g if element else 1l
    t2 = pow(r, key.n, key.n2)

    cipher = (t1 * t2) % key.n2
    return long(cipher)
예제 #20
0
def isPrime(N, randfunc=None):
    """isPrime(N:long, randfunc:callable):bool
    Return true if N is prime.

    If randfunc is omitted, then Random.new().read is used.
    """
    _import_Random()
    if randfunc is None:
        randfunc = Random.new().read

    randint = StrongRandom(randfunc=randfunc).randint

    if N == 1:
        return 0
    if N in sieve:
        return 1
    for i in sieve:
        if (N % i) == 0:
            return 0

    # Use the accelerator if available
    if _fastmath is not None:
        return _fastmath.isPrime(N)

    # Compute the highest bit that's set in N
    N1 = N - 1L
    n = 1L
    while (n < N):
        n = n << 1L
    n = n >> 1L

    # Rabin-Miller test
    for c in sieve[:7]:
        a = long(c)
        d = 1L
        t = n
        while (t):  # Iterate over the bits in N1
            x = (d * d) % N
            if x == 1L and d != 1L and d != N1:
                return 0  # Square root of 1 found
            if N1 & t:
                d = (x * a) % N
            else:
                d = x
            t = t >> 1L
        if d != 1L:
            return 0
예제 #21
0
class FileEncryptor(object, metaclass=abc.ABCMeta):

    __strong_random = StrongRandom()
    __lock = Lock()

    @classmethod
    def gen_secret(cls, min_length, max_length):
        with cls.__lock:
            n_chars = cls.__strong_random.randrange(min_length, max_length)
            return Random.new().read(n_chars)

    @abstractclassmethod
    def encrypt(cls, file_in, file_out, key_or_secret):
        pass

    @abstractclassmethod
    def decrypt(cls, file_in, file_out, key_or_secret):
        pass
예제 #22
0
    def generate_partial_decryption(self,
                                    ciphertext,
                                    task_monitor=None,
                                    force=False):
        """
        Generates a partial decryption for the given ciphertext.
        
        Arguments:
            ciphertext::Ciphertext    -- An encrypted Ciphertext object.
            task_monitor::TaskMonitor    -- A task monitor for this task.
            force:bool    -- Set this to true if you wish to force a decryption 
                           attempt, even when the ciphertext's stored public key
                           fingerprint does not match that of the public key 
                           associated with this private key.
        
        Returns:
            partial_decryption::PartialDecryption    -- A partial decryption of 
                                                       the given ciphertext 
                                                       generated with this 
                                                       threshold private key.
        
        Throws:
            IncompatibleCiphertextError -- The given ciphertext does not appear 
                                           to be decryptable with the selected 
                                           private key.
        """
        # Check that the public key fingerprint stored in the ciphertext
        # matches the public key associated with this private key.
        if (not force):
            if (ciphertext.nbits != self.cryptosystem.get_nbits()):
                raise IncompatibleCiphertextError("The given ciphertext is " \
                        "not decryptable with the selected private key: " \
                        "incompatible cryptosystem/key sizes.")

            if (ciphertext.pk_fingerprint !=
                    self.public_key.get_fingerprint()):
                raise IncompatibleCiphertextError("The given ciphertext is " \
                        "not decryptable with the selected private key: " \
                        "public key fingerprint mismatch.")

        nbits = self.cryptosystem.get_nbits()
        prime = self.cryptosystem.get_prime()
        generator = self.cryptosystem.get_generator()
        key = self._key

        # Remember that prime is of the form p = 2*q + 1, with q prime.
        # (By construction, see EGCryptoSystem)
        q = (prime - 1) / 2

        # We will need a random number generator for the proofs of partial
        # decryption.
        random = StrongRandom()

        # New empty partial decryption
        partial_decryption = PartialDecryption(nbits)

        # Check if we have a task monitor and register with it
        if (task_monitor != None):
            # One tick per block
            ticks = ciphertext.get_length()
            partial_decrypt_task_mon = \
                task_monitor.new_subtask("Generate partial decryption",
                                         expected_ticks = ticks)

        # For each (gamma,delta) component in the ciphertext, generate one
        # partial decryption block (with proof):
        for gamma, delta in ciphertext:

            # To calculate the value of the block, elevate gamma to the
            # threshold private key. That is block.value = g^{rP(i)} for each
            # nbits block of original plaintext.
            value = pow(gamma, key, prime)

            # Generate the partial decryption proof for the block as a
            # Zero-Knowledge Discrete Logarithm Equality Test for
            # log_{g}(g^{2P(j)}) == log_{gamma}(block^2)
            # (See PartialDecryptionBlockProof and [TODO: Add reference] for
            # more information.)

            # Select a random s in Z_{q}^{*}
            s = random.randint(1, q - 1)

            # a = g^{s} mod p
            a = pow(generator, s, prime)

            # b = gamma^{s} mod p
            b = pow(gamma, s, prime)

            # c is SHA256(a, b, g^{2*P(j)}, block.value) the challenge
            # (We must use g^{2*P(j)} and not g^{P(j)}, because the first is
            # considered as the partial public key of trustee j and the value
            # of the later is unavailable at decryption combination time).
            sha256 = Crypto.Hash.SHA256.new()
            sha256.update(hex(a))
            sha256.update(hex(b))
            sha256.update(hex(pow(generator, 2 * key, prime)))
            sha256.update(hex(value))
            c = int(sha256.hexdigest(), 16)

            # t = s + 2P(j)*c mod p-1 (P(j): trustee j's threshold private key)
            # (p - 1 since it is in the exponent and we are already adding the 2
            # factor in 2P(j))
            t = (s + 2 * key * c) % (prime - 1)

            # Generate the PartialDecryptionBlockProof as (a, b, t)
            proof = PartialDecryptionBlockProof(a, b, t)

            # Generate the block as (value, proof) and add it to the partial
            # decryption object.
            block = PartialDecryptionBlock(value, proof)
            partial_decryption.add_partial_decryption_block(block)

            # Update task progress
            if (task_monitor != None): partial_decrypt_task_mon.tick()

        return partial_decryption
예제 #23
0
    def encrypt_bitstream(self, bitstream, pad_to=None, task_monitor=None):
        """
        Encrypts the given bitstream into a ciphertext object.

        Arguments:
            bitstream::BitStream-- A stream of bits to encrypt
                                   (see BitStream utility class).
            pad_to::int            -- Minimum size (in bytes) of the resulting
                                   ciphertext. Data will be padded before
                                   encryption to match this size.
            task_monitor::TaskMonitor    -- A task monitor for this task.

        Returns:
            ciphertext:Ciphertext    -- A ciphertext object encapsulating the
                                       encrypted data.
        """
        random = StrongRandom()

        ## PART 1
        # First, format the bitstream as per Ciphertext.py Note 001,
        # previous to encryption.
        #     [size (64 bits) | message (size bits) | padding (X bits) ]
        ##
        formated_bitstream = BitStream()

        # The first 64 encode the size of the actual data in bits
        SIZE_BLOCK_LENGTH = 64
        size_in_bits = bitstream.get_length()

        if(size_in_bits >= 2**SIZE_BLOCK_LENGTH):
            raise ValueError("The size of the bitstream to encrypt is larger " \
                             "than 16 Exabits. The current format for  " \
                             "PloneVote ciphertext only allows encrypting a  " \
                             "maximum of 16 Exabits of information.")

        formated_bitstream.put_num(size_in_bits, SIZE_BLOCK_LENGTH)

        # We then copy the contents of the original bitstream
        bitstream.seek(0)
        formated_bitstream.put_bitstream_copy(bitstream)

        # Finally, we append random data until we reach the desired pad_to
        # length
        unpadded_length = formated_bitstream.get_length()
        if(pad_to != None and (pad_to * 8) > unpadded_length):
            full_length = pad_to * 8
        else:
            full_length = unpadded_length

        padding_left = full_length - unpadded_length

        while(padding_left > 1024):
            padding_bits = random.randint(1, 2**1024)
            formated_bitstream.put_num(padding_bits,1024)
            padding_left -= 1024

        if(padding_left > 0):
            padding_bits = random.randint(1, 2**padding_left)
            formated_bitstream.put_num(padding_bits, padding_left)
            padding_left = 0

        ## PART 2
        # We encrypt the formated bitsteam using ElGamal into a Ciphertext
        # object.
        # See "Handbook of Applied Cryptography" Algorithm 8.18
        ##

        # block_size is the size of each block of bits to encrypt
        # since we can only encrypt messages in [0, p - 1]
        # we should use (nbits - 1) as the block size, where
        # 2**(nbits - 1) < p < 2**nbits

        block_size = self.cryptosystem.get_nbits() - 1
        prime = self.cryptosystem.get_prime()
        generator = self.cryptosystem.get_generator()

        # We pull data from the bitstream one block at a time and encrypt it
        formated_bitstream.seek(0)
        ciphertext = \
            Ciphertext(self.cryptosystem.get_nbits(), self.get_fingerprint())

        plaintext_bits_left = formated_bitstream.get_length()

        # Check if we have a task monitor and register with it
        if(task_monitor != None):
            # We will do two tick()s per block to encrypt: one for generating
            # the gamma component of the ciphertext block and another for the
            # delta component (those are the two time intensive steps,
            # because of exponentiation).
            ticks = math.ceil((1.0 * plaintext_bits_left) / block_size) * 2
            encrypt_task_mon = \
                task_monitor.new_subtask("Encrypt data", expected_ticks = ticks)

        while(plaintext_bits_left > 0):

            # get next block (message, m, etc) to encrypt
            if(plaintext_bits_left >= block_size):
                block = formated_bitstream.get_num(block_size)
                plaintext_bits_left -= block_size
            else:
                block = formated_bitstream.get_num(plaintext_bits_left)
                # Encrypt as if the stream was filled with random data past its
                # end, this avoids introducing a 0's gap during decryption to
                # bitstream
                displacement = block_size - plaintext_bits_left
                block = block << displacement
                padding = random.randint(0, 2**displacement - 1)
                assert (padding // 2**displacement == 0), \
                            "padding should be at most displacement bits long"
                block = block | padding
                plaintext_bits_left = 0

            # Select a random integer k, 1 <= k <= p − 2
            k = random.randint(1, prime - 2)

            # Compute gamma and delta
            gamma = pow(generator, k, prime)
            if(task_monitor != None): encrypt_task_mon.tick()

            delta = (block * pow(self._key, k, prime)) % prime
            if(task_monitor != None): encrypt_task_mon.tick()

            # Add this encrypted data portion to the ciphertext object
            ciphertext.append(gamma, delta)

        # return the ciphertext object
        return ciphertext
예제 #24
0
def getRandomPassword(length):
	sr = StrongRandom()
	return ''.join(sr.choice(password_chars) for x in range(length))
예제 #25
0
 def __init__(self):
     self.rnd = StrongRandom()
예제 #26
0
def main():
    print ''


print 'm', m
# Secret generation
a = []
a.append(generateSecret())

secretCount = numberOfSecrets * userCount - 1
print 'secretCount', secretCount
for x in xrange(0, secretCount):
    a.append(generateSecret())
secretArray = a

print 'secretArray', secretArray
chunks = [
    secretArray[x:x + numberOfSecrets]
    for x in xrange(0, len(secretArray), numberOfSecrets)
]
print 'chunks', chunks

# Use strong random to shuffle the array. This way our crypto program is secure
(StrongRandom()).shuffle(secretArray)
print 'secretArray', secretArray

# user 1
things = [User1(), User2()]
total = decryptData(things, 1, secretArray)
print total
def create_rng(tag):
    rng = StrongRandom(SHAKE128.new(data=tag))
    return rng
예제 #28
0
"""
Crypto Utils
"""
import base64
import math

from Crypto.Hash import SHA256
from Crypto.Random.random import StrongRandom

random = StrongRandom()


def random_mpz_lt(maximum, strong_random=random):
    n_bits = int(math.floor(math.log(maximum, 2)))
    res = strong_random.getrandbits(n_bits)
    while res >= maximum:
        res = strong_random.getrandbits(n_bits)
    return res


random.mpz_lt = random_mpz_lt


def hash_b64(s):
    """
    hash the string using sha256 and produce a base64 output
    removes the trailing "="
    """
    hasher = SHA256.new(s.encode('utf-8'))
    result = base64.b64encode(hasher.digest())[:-1]
    return result
예제 #29
0
def generate_random(nbytes):
    ''' returns nbytes-long random string '''
    return ''.join(chr(StrongRandom().randint(0, 0xFF)) for i in range(nbytes))
예제 #30
0
from __future__ import absolute_import, division, print_function
from __future__ import unicode_literals
from builtins import *
import logging
import struct
import time

try:
    from Crypto.Random.random import StrongRandom
    # Wrap with int() for Py2
    random = lambda n: int(StrongRandom().getrandbits(n * 8)).to_bytes(
        n, 'big')
except ImportError:
    from os import urandom as random

try:
    from . import crypto
except ImportError:
    crypto = None

from i2p import util

if crypto:
    sha256 = crypto.sha256
else:
    sha256 = util.sha256

from enum import Enum

#
# Common data types
예제 #31
0
 def generate_partial_decryption(self, ciphertext, task_monitor=None, 
                                 force=False):
     """
     Generates a partial decryption for the given ciphertext.
     
     Arguments:
         ciphertext::Ciphertext    -- An encrypted Ciphertext object.
         task_monitor::TaskMonitor    -- A task monitor for this task.
         force:bool    -- Set this to true if you wish to force a decryption 
                        attempt, even when the ciphertext's stored public key
                        fingerprint does not match that of the public key 
                        associated with this private key.
     
     Returns:
         partial_decryption::PartialDecryption    -- A partial decryption of 
                                                    the given ciphertext 
                                                    generated with this 
                                                    threshold private key.
     
     Throws:
         IncompatibleCiphertextError -- The given ciphertext does not appear 
                                        to be decryptable with the selected 
                                        private key.
     """
     # Check that the public key fingerprint stored in the ciphertext 
     # matches the public key associated with this private key.
     if(not force):
         if(ciphertext.nbits != self.cryptosystem.get_nbits()):
             raise IncompatibleCiphertextError("The given ciphertext is " \
                     "not decryptable with the selected private key: " \
                     "incompatible cryptosystem/key sizes.")
         
         if(ciphertext.pk_fingerprint != self.public_key.get_fingerprint()):
             raise IncompatibleCiphertextError("The given ciphertext is " \
                     "not decryptable with the selected private key: " \
                     "public key fingerprint mismatch.")
     
     nbits = self.cryptosystem.get_nbits()
     prime = self.cryptosystem.get_prime()
     generator = self.cryptosystem.get_generator()
     key = self._key
     
     # Remember that prime is of the form p = 2*q + 1, with q prime.
     # (By construction, see EGCryptoSystem)
     q = (prime - 1)/2
     
     # We will need a random number generator for the proofs of partial 
     # decryption.
     random = StrongRandom()
     
     # New empty partial decryption
     partial_decryption = PartialDecryption(nbits)
     
     # Check if we have a task monitor and register with it
     if(task_monitor != None):
         # One tick per block
         ticks = ciphertext.get_length()
         partial_decrypt_task_mon = \
             task_monitor.new_subtask("Generate partial decryption", 
                                      expected_ticks = ticks)
     
     # For each (gamma,delta) component in the ciphertext, generate one  
     # partial decryption block (with proof):
     for gamma, delta in ciphertext:
     
         # To calculate the value of the block, elevate gamma to the 
         # threshold private key. That is block.value = g^{rP(i)} for each 
         # nbits block of original plaintext.
         value = pow(gamma, key, prime)
         
         # Generate the partial decryption proof for the block as a
         # Zero-Knowledge Discrete Logarithm Equality Test for 
         # log_{g}(g^{2P(j)}) == log_{gamma}(block^2)
         # (See PartialDecryptionBlockProof and [TODO: Add reference] for 
         # more information.)
         
         # Select a random s in Z_{q}^{*}
         s = random.randint(1, q - 1)
         
         # a = g^{s} mod p
         a = pow(generator, s, prime)
         
         # b = gamma^{s} mod p
         b = pow(gamma, s, prime)
         
         # c is SHA256(a, b, g^{2*P(j)}, block.value) the challenge
         # (We must use g^{2*P(j)} and not g^{P(j)}, because the first is 
         # considered as the partial public key of trustee j and the value 
         # of the later is unavailable at decryption combination time).
         sha256 =  Crypto.Hash.SHA256.new()
         sha256.update(hex(a))
         sha256.update(hex(b))
         sha256.update(hex(pow(generator, 2*key, prime)))
         sha256.update(hex(value))
         c = int(sha256.hexdigest(),16)
         
         # t = s + 2P(j)*c mod p-1 (P(j): trustee j's threshold private key)
         # (p - 1 since it is in the exponent and we are already adding the 2
         # factor in 2P(j))
         t = (s + 2*key*c) % (prime - 1)
         
         # Generate the PartialDecryptionBlockProof as (a, b, t)
         proof = PartialDecryptionBlockProof(a, b, t)
         
         # Generate the block as (value, proof) and add it to the partial 
         # decryption object.
         block = PartialDecryptionBlock(value, proof)
         partial_decryption.add_partial_decryption_block(block)
         
         # Update task progress
         if(task_monitor != None): partial_decrypt_task_mon.tick()
     
     return partial_decryption
예제 #32
0
from Crypto.Cipher import AES, PKCS1_OAEP
from Crypto.Signature import PKCS1_PSS
from Crypto.Hash import SHA
from Crypto import Random
from Crypto.Random.random import StrongRandom
from Crypto.PublicKey import RSA
import binascii

cryptoRNG = Random.new()  #random number generator
strongRandom = StrongRandom()
'''---------------The Encryption Abstraction----------------'''

constPadString = u"dkgh;slfdkgukrjfdkgh;slfdkgukrjf"


def preprocessString(inpString):  #pad to length of size 32
    return (inpString + u"$" + constPadString)[:32]


def unpreprocessString(inpString):
    for i in range(len(inpString)):
        if inpString[i] == '$':
            break
    return inpString[:i]


AESInitializationVector = "jhfdiyeqkjxjvgljdfhsdkjghdsflcgf"[:16]


def symmetricEncrypt(inpString, key):
    cipher = AES.new(preprocessString(key), AES.MODE_CFB,
예제 #33
0
 def random_int_wrapper(nbytes):
     """returns a random integer in [0, 256**nbytes -1 ]"""
     return StrongRandom().randint(0,256**nbytes - 1)
예제 #34
0
 def encrypt_bitstream(self, bitstream, pad_to=None, task_monitor=None):
     """
     Encrypts the given bitstream into a ciphertext object.
     
     Arguments:
         bitstream::BitStream-- A stream of bits to encrypt 
                                (see BitStream utility class).
         pad_to::int            -- Minimum size (in bytes) of the resulting 
                                ciphertext. Data will be padded before 
                                encryption to match this size.
         task_monitor::TaskMonitor    -- A task monitor for this task.
     
     Returns:
         ciphertext:Ciphertext    -- A ciphertext object encapsulating the 
                                    encrypted data.        
     """
     random = StrongRandom()
     
     ## PART 1
     # First, format the bitstream as per Ciphertext.py Note 001,
     # previous to encryption.
     #     [size (64 bits) | message (size bits) | padding (X bits) ]
     ##
     formated_bitstream = BitStream()
     
     # The first 64 encode the size of the actual data in bits
     SIZE_BLOCK_LENGTH = 64
     size_in_bits = bitstream.get_length()
     
     if(size_in_bits >= 2**SIZE_BLOCK_LENGTH):
         raise ValueError("The size of the bitstream to encrypt is larger " \
                          "than 16 Exabits. The current format for  " \
                          "PloneVote ciphertext only allows encrypting a  " \
                          "maximum of 16 Exabits of information.")
     
     formated_bitstream.put_num(size_in_bits, SIZE_BLOCK_LENGTH)
     
     # We then copy the contents of the original bitstream
     bitstream.seek(0)
     formated_bitstream.put_bitstream_copy(bitstream)
     
     # Finally, we append random data until we reach the desired pad_to 
     # length
     unpadded_length = formated_bitstream.get_length()
     if(pad_to != None and (pad_to * 8) > unpadded_length):
         full_length = pad_to * 8
     else:
         full_length = unpadded_length
     
     padding_left = full_length - unpadded_length
     
     while(padding_left > 1024):
         padding_bits = random.randint(1, 2**1024)
         formated_bitstream.put_num(padding_bits,1024)
         padding_left -= 1024
     
     if(padding_left > 0):
         padding_bits = random.randint(1, 2**padding_left)
         formated_bitstream.put_num(padding_bits, padding_left)
         padding_left = 0
     
     ## PART 2
     # We encrypt the formated bitsteam using ElGamal into a Ciphertext 
     # object.
     # See "Handbook of Applied Cryptography" Algorithm 8.18
     ##
     
     # block_size is the size of each block of bits to encrypt
     # since we can only encrypt messages in [0, p - 1]
     # we should use (nbits - 1) as the block size, where 
     # 2**(nbits - 1) < p < 2**nbits
     
     block_size = self.cryptosystem.get_nbits() - 1
     prime = self.cryptosystem.get_prime()
     generator = self.cryptosystem.get_generator()
     
     # We pull data from the bitstream one block at a time and encrypt it
     formated_bitstream.seek(0)
     ciphertext = \
         Ciphertext(self.cryptosystem.get_nbits(), self.get_fingerprint()) 
     
     plaintext_bits_left = formated_bitstream.get_length()
     
     # Check if we have a task monitor and register with it
     if(task_monitor != None):
         # We will do two tick()s per block to encrypt: one for generating 
         # the gamma component of the ciphertext block and another for the 
         # delta component (those are the two time intensive steps, 
         # because of exponentiation). 
         ticks = math.ceil((1.0 * plaintext_bits_left) / block_size) * 2
         encrypt_task_mon = \
             task_monitor.new_subtask("Encrypt data", expected_ticks = ticks)
     
     while(plaintext_bits_left > 0):
     
         # get next block (message, m, etc) to encrypt
         if(plaintext_bits_left >= block_size):
             block = formated_bitstream.get_num(block_size)
             plaintext_bits_left -= block_size
         else:
             block = formated_bitstream.get_num(plaintext_bits_left)
             # Encrypt as if the stream was filled with random data past its 
             # end, this avoids introducing a 0's gap during decryption to 
             # bitstream
             displacement = block_size - plaintext_bits_left
             block = block << displacement
             padding = random.randint(0, 2**displacement - 1)
             assert (padding / 2**displacement == 0), \
                         "padding should be at most displacement bits long"
             block = block | padding
             plaintext_bits_left = 0
         
         # Select a random integer k, 1 <= k <= p − 2
         k = random.randint(1, prime - 2)
         
         # Compute gamma and delta
         gamma = pow(generator, k, prime)
         if(task_monitor != None): encrypt_task_mon.tick()
         
         delta = (block * pow(self._key, k, prime)) % prime
         if(task_monitor != None): encrypt_task_mon.tick()
         
         # Add this encrypted data portion to the ciphertext object
         ciphertext.append(gamma, delta)
     
     # return the ciphertext object
     return ciphertext
예제 #35
0
def generate_salt():
    rand = StrongRandom()
    return str(rand.getrandbits(256))