示例#1
0
    def _encrypt(self, plaintext, output):
        """Encrypt without FSM checks"""
        
        if output is None:
            ciphertext = create_string_buffer(len(plaintext))
        else:
            ciphertext = output
            
            if not is_writeable_buffer(output):
                raise TypeError("output must be a bytearray or a writeable memoryview")
        
            if len(plaintext) != len(output):
                raise ValueError("output must have the same length as the input"
                                 "  (%d bytes)" % len(plaintext))

        result = _raw_chacha20_lib.chacha20_encrypt(
                                         self._state.get(),
                                         c_uint8_ptr(plaintext),
                                         c_uint8_ptr(ciphertext),
                                         c_size_t(len(plaintext)))
        if result:
            raise ValueError("Error %d while encrypting with ChaCha20" % result)
        
        if output is None:
            return get_raw_buffer(ciphertext)
        else:
            return None
示例#2
0
    def _transcrypt_aligned(self, in_data, in_data_len, trans_func, trans_desc):

        out_data = create_string_buffer(in_data_len)
        result = trans_func(self._state.get(), in_data, out_data, c_size_t(in_data_len))
        if result:
            raise ValueError("Error %d while %sing in OCB mode" % (result, trans_desc))
        return get_raw_buffer(out_data)
示例#3
0
    def encrypt(self, plaintext):
        """Encrypt data with the key set at initialization.

        The data to encrypt can be broken up in two or
        more pieces and `encrypt` can be called multiple times.

        That is, the statement:

            >>> c.encrypt(a) + c.encrypt(b)

        is equivalent to:

             >>> c.encrypt(a+b)

        This function does not add any padding to the plaintext.

        :Parameters:
          plaintext : byte string
            The piece of data to encrypt.
            The length must be multiple of the cipher block length.
        :Return:
            the encrypted data, as a byte string.
            It is as long as *plaintext*.
        """

        expect_byte_string(plaintext)
        ciphertext = create_string_buffer(len(plaintext))
        result = raw_ecb_lib.ECB_encrypt(self._state.get(),
                                         plaintext,
                                         ciphertext,
                                         c_size_t(len(plaintext)))
        if result:
            raise ValueError("Error %d while encrypting in ECB mode" % result)
        return get_raw_buffer(ciphertext)
示例#4
0
文件: SHAKE128.py 项目: cloudera/hue
    def read(self, length):
        """
        Compute the next piece of XOF output.

        .. note::
            You cannot use :meth:`update` anymore after the first call to
            :meth:`read`.

        Args:
            length (integer): the amount of bytes this method must return

        :return: the next piece of XOF output (of the given length)
        :rtype: byte string
        """

        self._is_squeezing = True
        bfr = create_string_buffer(length)
        result = _raw_keccak_lib.keccak_squeeze(self._state.get(),
                                                bfr,
                                                c_size_t(length))
        if result:
            raise ValueError("Error %d while extracting from SHAKE128"
                             % result)

        return get_raw_buffer(bfr)
示例#5
0
def strxor_c(term, c):
    """Return term xored with a sequence of characters c."""

    expect_byte_string(term)
    if not 0 <= c < 256:
        raise ValueError("c must be in range(256)")
    result = create_string_buffer(len(term))
    _raw_strxor.strxor_c(term, c, result, c_size_t(len(term)))
    return get_raw_buffer(result)
示例#6
0
    def __int__(self):
        # buf will contain the integer encoded in decimal plus the trailing
        # zero, and possibly the negative sign.
        # dig10(x) < log10(x) + 1 = log2(x)/log2(10) + 1 < log2(x)/3 + 1
        buf_len = _gmp.mpz_sizeinbase(self._mpz_p, 2) // 3 + 3
        buf = create_string_buffer(buf_len)

        _gmp.gmp_snprintf(buf, c_size_t(buf_len), b("%Zd"), self._mpz_p)
        return int(get_c_string(buf))
示例#7
0
文件: KDF.py 项目: shubhanus/taiga
def _scryptBlockMix(blocks, len_blocks):
    """Hash function for ROMix."""

    x = blocks[-1]
    core = _raw_salsa20_lib.Salsa20_8_core
    result = [ create_string_buffer(64) for _ in range(len(blocks)) ]
    for i in range(len(blocks)):
        core(x, blocks[i], result[i])
        x = result[i]
    return [result[i + j] for j in range(2)
            for i in range(0, len_blocks, 2)]
示例#8
0
    def encrypt(self, plaintext, output=None):
        """Encrypt data with the key set at initialization.

        The data to encrypt can be broken up in two or
        more pieces and `encrypt` can be called multiple times.

        That is, the statement:

            >>> c.encrypt(a) + c.encrypt(b)

        is equivalent to:

             >>> c.encrypt(a+b)

        This function does not add any padding to the plaintext.

        :Parameters:
          plaintext : bytes/bytearray/memoryview
            The piece of data to encrypt.
            The length must be multiple of the cipher block length.
        :Keywords:
          output : bytearray/memoryview
            The location where the ciphertext must be written to.
            If ``None``, the ciphertext is returned.
        :Return:
          If ``output`` is ``None``, the ciphertext is returned as ``bytes``.
          Otherwise, ``None``.
        """

        if output is None:
            ciphertext = create_string_buffer(len(plaintext))
        else:
            ciphertext = output
            
            if not is_writeable_buffer(output):
                raise TypeError("output must be a bytearray or a writeable memoryview")
        
            if len(plaintext) != len(output):
                raise ValueError("output must have the same length as the input"
                                 "  (%d bytes)" % len(plaintext))

        result = raw_ecb_lib.ECB_encrypt(self._state.get(),
                                         c_uint8_ptr(plaintext),
                                         c_uint8_ptr(ciphertext),
                                         c_size_t(len(plaintext)))
        if result:
            if result == 3:
                raise ValueError("Data must be aligned to block boundary in ECB mode")
            raise ValueError("Error %d while encrypting in ECB mode" % result)
        
        if output is None:
            return get_raw_buffer(ciphertext)
        else:
            return None
示例#9
0
def strxor(term1, term2):
    """Return term1 xored with term2.
    The two byte strings must have equal length."""

    expect_byte_string(term1)
    expect_byte_string(term2)
    if len(term1) != len(term2):
        raise ValueError("Only byte strings of equal length can be xored")
    result = create_string_buffer(len(term1))
    _raw_strxor.strxor(term1, term2, result, c_size_t(len(term1)))
    return get_raw_buffer(result)
示例#10
0
def strxor_c(term, c):
    """XOR of a byte string with a repeated sequence of characters.

    Return:
        A new byte string, :data:`term` with all its bytes xored with :data:`c`.
    """

    if not 0 <= c < 256:
        raise ValueError("c must be in range(256)")
    result = create_string_buffer(len(term))
    _raw_strxor.strxor_c(c_uint8_ptr(term), c, result, c_size_t(len(term)))
    return get_raw_buffer(result)
    def _encrypt(self, plaintext):
        """Encrypt without FSM checks"""

        ciphertext = create_string_buffer(len(plaintext))
        result = _raw_chacha20_lib.chacha20_encrypt(
                                         self._state.get(),
                                         c_uint8_ptr(plaintext),
                                         ciphertext,
                                         c_size_t(len(plaintext)))
        if result:
            raise ValueError("Error %d while encrypting with ChaCha20" % result)
        return get_raw_buffer(ciphertext)
示例#12
0
    def _compute_mac_tag(self):

        if self._mac_tag is not None:
            return

        if self._cache_A:
            self._update(self._cache_A, len(self._cache_A))
            self._cache_A = b("")

        mac_tag = create_string_buffer(16)
        result = _raw_ocb_lib.OCB_digest(self._state.get(), mac_tag, c_size_t(len(mac_tag)))
        if result:
            raise ValueError("Error %d while computing digest in OCB mode" % result)
        self._mac_tag = get_raw_buffer(mac_tag)[: self._mac_len]
示例#13
0
    def __init__(self, subkey):
        assert len(subkey) == 16

        self._exp_key = VoidPointer()
        result = _raw_galois_lib.ghash_expand(c_uint8_ptr(subkey),
                                              self._exp_key.address_of())
        if result:
            raise ValueError("Error %d while expanding the GMAC key" % result)

        self._exp_key = SmartPointer(self._exp_key.get(),
                                     _raw_galois_lib.ghash_destroy)

        # create_string_buffer always returns a string of zeroes
        self._last_y = create_string_buffer(16)
示例#14
0
    def inplace_pow(self, exponent, modulus=None):
        exp_value = int(exponent)
        if exp_value < 0:
            raise ValueError("Exponent must not be negative")

        # No modular reduction
        if modulus is None:
            self._value = pow(self._value, exp_value)
            return self

        # With modular reduction
        mod_value = int(modulus)
        if mod_value < 0:
            raise ValueError("Modulus must be positive")
        if mod_value == 0:
            raise ZeroDivisionError("Modulus cannot be zero")

        # C extension only works with odd moduli
        if (mod_value & 1) == 0:
            self._value = pow(self._value, exp_value, mod_value)
            return self

        # C extension only works with bases smaller than modulus
        if self._value >= mod_value:
            self._value %= mod_value

        max_len = len(long_to_bytes(max(self._value, exp_value, mod_value)))

        base_b = long_to_bytes(self._value, max_len)
        exp_b = long_to_bytes(exp_value, max_len)
        modulus_b = long_to_bytes(mod_value, max_len)

        out = create_string_buffer(max_len)

        error = _raw_montgomery.monty_pow(
                    out,
                    base_b,
                    exp_b,
                    modulus_b,
                    c_size_t(max_len),
                    c_ulonglong(getrandbits(64))
                    )

        if error:
            raise ValueError("monty_pow failed with error: %d" % error)

        result = bytes_to_long(get_raw_buffer(out))
        self._value = result
        return self
示例#15
0
文件: strxor.py 项目: cloudera/hue
def strxor(term1, term2):
    """XOR of two byte strings.
    They must have equal length.

    Return:
        A new byte string, :data:`term1` xored with :data:`term2`.
    """

    expect_byte_string(term1)
    expect_byte_string(term2)
    if len(term1) != len(term2):
        raise ValueError("Only byte strings of equal length can be xored")
    result = create_string_buffer(len(term1))
    _raw_strxor.strxor(term1, term2, result, c_size_t(len(term1)))
    return get_raw_buffer(result)
示例#16
0
    def __init__(self, hash_subkey, block_size):
        _SmoothMAC.__init__(self, block_size, None, 0)

        self._key = hash_subkey
        self._exp_key = VoidPointer()
        expect_byte_string(self._key)
        result = _raw_galois_lib.ghash_expand(self._key, self._exp_key.address_of())
        if result:
            raise ValueError("Error %d while expanding the GMAC key" % result)
        self._exp_key = SmartPointer(self._exp_key.get(), _raw_galois_lib.ghash_destroy)

        self._last_y = create_string_buffer(16)
        for i in xrange(16):
            self._last_y[i] = bchr(0)
        self._mac = _raw_galois_lib.ghash
示例#17
0
    def digest(self):
        """Return the **binary** (non-printable) digest of the message that has been hashed so far.

        :return: The hash digest, computed over the data processed so far.
                 Binary form.
        :rtype: byte string
        """

        bfr = create_string_buffer(self.digest_size)
        result = _raw_ripemd160_lib.ripemd160_digest(self._state.get(),
                                                     bfr)
        if result:
            raise ValueError("Error %d while instantiating ripemd160"
                             % result)

        return get_raw_buffer(bfr)
示例#18
0
    def encrypt(self, plaintext):
        """Encrypt a piece of data.

        :Parameters:
          plaintext : byte string
            The piece of data to encrypt. It can be of any size.
        :Return: the encrypted data (byte string, as long as the
          plaintext).
        """

        expect_byte_string(plaintext)
        ciphertext = create_string_buffer(len(plaintext))
        result = _raw_arc4_lib.ARC4_stream_encrypt(self._state.get(), plaintext, ciphertext, c_size_t(len(plaintext)))
        if result:
            raise ValueError("Error %d while encrypting with RC4" % result)
        return get_raw_buffer(ciphertext)
示例#19
0
    def read(self, length):
        """Return the next ``length`` bytes of **binary** (non-printable)
        digest for the message.

        You cannot use ``update`` anymore after the first call to ``read``.

        :Return: A byte string of `length` bytes.
        """

        self._is_squeezing = True
        bfr = create_string_buffer(length)
        result = _raw_keccak_lib.keccak_squeeze(self._state.get(), bfr, c_size_t(length))
        if result:
            raise ValueError("Error %d while extracting from SHAKE256" % result)

        return get_raw_buffer(bfr)
示例#20
0
    def __init__(self, subkey):
        assert len(subkey) == 16

        expect_byte_string(subkey)
        self._exp_key = VoidPointer()
        result = _raw_galois_lib.ghash_expand(subkey,
                                              self._exp_key.address_of())
        if result:
            raise ValueError("Error %d while expanding the GMAC key" % result)

        self._exp_key = SmartPointer(self._exp_key.get(),
                                     _raw_galois_lib.ghash_destroy)

        self._last_y = create_string_buffer(16)
        for i in range(16):
            self._last_y[i] = bchr(0)
    def encrypt(self, plaintext):
        """Encrypt data with the key and the parameters set at initialization.

        A cipher object is stateful: once you have encrypted a message
        you cannot encrypt (or decrypt) another message using the same
        object.

        The data to encrypt can be broken up in two or
        more pieces and `encrypt` can be called multiple times.

        That is, the statement:

            >>> c.encrypt(a) + c.encrypt(b)

        is equivalent to:

             >>> c.encrypt(a+b)

        That also means that you cannot reuse an object for encrypting
        or decrypting other data with the same key.

        This function does not add any padding to the plaintext.

        :Parameters:
          plaintext : bytes/bytearray/memoryview
            The piece of data to encrypt.
            Its lenght must be multiple of the cipher block size.
        :Return:
            the encrypted data, as a byte string.
            It is as long as *plaintext*.
        """

        if self.encrypt not in self._next:
            raise TypeError("encrypt() cannot be called after decrypt()")
        self._next = [ self.encrypt ]

        ciphertext = create_string_buffer(len(plaintext))
        result = raw_cbc_lib.CBC_encrypt(self._state.get(),
                                         c_uint8_ptr(plaintext),
                                         ciphertext,
                                         c_size_t(len(plaintext)))
        if result:
            if result == 3:
                raise ValueError("Data must be padded to %d byte boundary in CBC mode" % self.block_size)
            raise ValueError("Error %d while encrypting in CBC mode" % result)
        return get_raw_buffer(ciphertext)
示例#22
0
文件: BLAKE2b.py 项目: cloudera/hue
    def digest(self):
        """Return the **binary** (non-printable) digest of the message that has been hashed so far.

        :return: The hash digest, computed over the data processed so far.
                 Binary form.
        :rtype: byte string
        """

        bfr = create_string_buffer(64)
        result = _raw_blake2b_lib.blake2b_digest(self._state.get(),
                                                 bfr)
        if result:
            raise ValueError("Error %d while creating BLAKE2b digest" % result)

        self._digest_done = True

        return get_raw_buffer(bfr)[:self.digest_size]
    def encrypt(self, plaintext):
        """Encrypt a piece of data.

        :param plaintext: The data to encrypt, of any size.
        :type plaintext: bytes, bytearray, memoryview
        :returns: the encrypted byte string, of equal length as the
          plaintext.
        """

        ciphertext = create_string_buffer(len(plaintext))
        result = _raw_arc4_lib.ARC4_stream_encrypt(self._state.get(),
                                                   c_uint8_ptr(plaintext),
                                                   ciphertext,
                                                   c_size_t(len(plaintext)))
        if result:
            raise ValueError("Error %d while encrypting with RC4" % result)
        return get_raw_buffer(ciphertext)
示例#24
0
文件: keccak.py 项目: cloudera/hue
    def digest(self):
        """Return the **binary** (non-printable) digest of the message that has been hashed so far.

        :return: The hash digest, computed over the data processed so far.
                 Binary form.
        :rtype: byte string
        """

        self._digest_done = True
        bfr = create_string_buffer(self.digest_size)
        result = _raw_keccak_lib.keccak_digest(self._state.get(),
                                               bfr,
                                               c_size_t(self.digest_size))
        if result:
            raise ValueError("Error %d while squeezing keccak" % result)

        return get_raw_buffer(bfr)
示例#25
0
    def digest(self):
        """Return the **binary** (non-printable) digest of the message that has been hashed so far.

        :return: The hash digest, computed over the data processed so far.
                 Binary form.
        :rtype: byte string
        """

        bfr = create_string_buffer(self.digest_size)
        result = _raw_sha256_lib.SHA256_digest(self._state.get(),
                                               bfr,
                                               c_size_t(self.digest_size))
        if result:
            raise ValueError("Error %d while making SHA256 digest"
                             % result)

        return get_raw_buffer(bfr)
示例#26
0
    def encrypt(self, plaintext):
        """Encrypt data with the key and the parameters set at initialization.

        A cipher object is stateful: once you have encrypted a message
        you cannot encrypt (or decrypt) another message using the same
        object.

        The data to encrypt can be broken up in two or
        more pieces and `encrypt` can be called multiple times.

        That is, the statement:

            >>> c.encrypt(a) + c.encrypt(b)

        is equivalent to:

             >>> c.encrypt(a+b)

        This function does not add any padding to the plaintext.

        :Parameters:
          plaintext : byte string
            The piece of data to encrypt.
            It can be of any length.
        :Return:
            the encrypted data, as a byte string.
            It is as long as *plaintext*.
        """

        if self.encrypt not in self._next:
            raise TypeError("encrypt() cannot be called after decrypt()")
        self._next = [self.encrypt]

        expect_byte_string(plaintext)
        ciphertext = create_string_buffer(len(plaintext))
        result = raw_ctr_lib.CTR_encrypt(self._state.get(),
                                         plaintext,
                                         ciphertext,
                                         c_size_t(len(plaintext)))
        if result:
            if result == 0x60002:
                raise OverflowError("The counter has wrapped around in"
                                    " CTR mode")
            raise ValueError("Error %X while encrypting in CTR mode" % result)
        return get_raw_buffer(ciphertext)
示例#27
0
    def digest(self):
        """Return the **binary** (non-printable) digest of the message that has been hashed so far.

        This method does not change the state of the hash object.
        You can continue updating the object after calling this function.

        :Return: A byte string of `digest_size` bytes. It may contain non-ASCII
         characters, including null bytes.
        """

        bfr = create_string_buffer(self.digest_size)
        result = _raw_sha3_384_lib.SHA3_384_digest(self._state.get(),
                                                   bfr)
        if result:
            raise ValueError("Error %d while instantiating SHA-3/384"
                             % result)

        return get_raw_buffer(bfr)
示例#28
0
def _pbkdf2_hmac_assist(inner, outer, first_digest, iterations):
    """Compute the expensive inner loop in PBKDF-HMAC."""

    assert iterations > 0

    bfr = create_string_buffer(len(first_digest));
    result = _raw_sha256_lib.SHA256_pbkdf2_hmac_assist(
                    inner._state.get(),
                    outer._state.get(),
                    first_digest,
                    bfr,
                    c_size_t(iterations),
                    c_size_t(len(first_digest)))

    if result:
        raise ValueError("Error %d with PBKDF2-HMAC assist for SHA256" % result)

    return get_raw_buffer(bfr)
示例#29
0
    def decrypt(self, ciphertext):
        """Decrypt data with the key and the parameters set at initialization.

        A cipher object is stateful: once you have decrypted a message
        you cannot decrypt (or encrypt) another message with the same
        object.

        The data to decrypt can be broken up in two or
        more pieces and `decrypt` can be called multiple times.

        That is, the statement:

            >>> c.decrypt(a) + c.decrypt(b)

        is equivalent to:

             >>> c.decrypt(a+b)

        This function does not remove any padding from the plaintext.

        :Parameters:
          ciphertext : bytes/bytearray/memoryview
            The piece of data to decrypt.
            It can be of any length.

        :Return: the decrypted data (byte string).
        """

        if self.decrypt not in self._next:
            raise TypeError("decrypt() cannot be called after encrypt()")
        self._next = [self.decrypt]

        plaintext = create_string_buffer(len(ciphertext))
        result = raw_ctr_lib.CTR_decrypt(self._state.get(),
                                         c_uint8_ptr(ciphertext),
                                         plaintext,
                                         c_size_t(len(ciphertext)))
        if result:
            if result == 0x60002:
                raise OverflowError("The counter has wrapped around in"
                                    " CTR mode")
            raise ValueError("Error %X while decrypting in CTR mode" % result)
        return get_raw_buffer(plaintext)
示例#30
0
文件: Salsa20.py 项目: cloudera/hue
    def encrypt(self, plaintext):
        """Encrypt a piece of data.

        :param plaintext: The data to encrypt, of any size.
        :type plaintext: byte string
        :returns: the encrypted byte string, of equal length as the
          plaintext.
        """

        expect_byte_string(plaintext)
        ciphertext = create_string_buffer(len(plaintext))
        result = _raw_salsa20_lib.Salsa20_stream_encrypt(
                                         self._state.get(),
                                         plaintext,
                                         ciphertext,
                                         c_size_t(len(plaintext)))
        if result:
            raise ValueError("Error %d while encrypting with Salsa20" % result)
        return get_raw_buffer(ciphertext)
示例#31
0
    def decrypt(self, ciphertext, output=None):
        """Decrypt data with the key and the parameters set at initialization.

        A cipher object is stateful: once you have decrypted a message
        you cannot decrypt (or encrypt) another message with the same
        object.

        The data to decrypt can be broken up in two or
        more pieces and `decrypt` can be called multiple times.

        That is, the statement:

            >>> c.decrypt(a) + c.decrypt(b)

        is equivalent to:

             >>> c.decrypt(a+b)

        This function does not remove any padding from the plaintext.

        :Parameters:
          ciphertext : bytes/bytearray/memoryview
            The piece of data to decrypt.
            Its length must be multiple of the cipher block size.
        :Keywords:
          output : bytearray/memoryview
            The location where the plaintext must be written to.
            If ``None``, the plaintext is returned.
        :Return:
          If ``output`` is ``None``, the plaintext is returned as ``bytes``.
          Otherwise, ``None``.
        """

        if self.decrypt not in self._next:
            raise TypeError("decrypt() cannot be called after encrypt()")
        self._next = [self.decrypt]

        if output is None:
            plaintext = create_string_buffer(len(ciphertext))
        else:
            plaintext = output

            if not is_writeable_buffer(output):
                raise TypeError(
                    "output must be a bytearray or a writeable memoryview")

            if len(ciphertext) != len(output):
                raise ValueError(
                    "output must have the same length as the input"
                    "  (%d bytes)" % len(plaintext))

        result = raw_cbc_lib.CBC_decrypt(self._state.get(),
                                         c_uint8_ptr(ciphertext),
                                         c_uint8_ptr(plaintext),
                                         c_size_t(len(ciphertext)))
        if result:
            if result == 3:
                raise ValueError(
                    "Data must be padded to %d byte boundary in CBC mode" %
                    self.block_size)
            raise ValueError("Error %d while decrypting in CBC mode" % result)

        if output is None:
            return get_raw_buffer(plaintext)
        else:
            return None
示例#32
0
def scrypt(password, salt, key_len, N, r, p, num_keys=1):
    """Derive one or more keys from a passphrase.

    This function performs key derivation according to
    the `scrypt`_ algorithm, introduced in Percival's paper
    `"Stronger key derivation via sequential memory-hard functions"`__.

    This implementation is based on `RFC7914`__.

    Args:
     password (string):
        The secret pass phrase to generate the keys from.
     salt (string):
        A string to use for better protection from dictionary attacks.
        This value does not need to be kept secret,
        but it should be randomly chosen for each derivation.
        It is recommended to be at least 8 bytes long.
     key_len (integer):
        The length in bytes of every derived key.
     N (integer):
        CPU/Memory cost parameter. It must be a power of 2 and less
        than :math:`2^{32}`.
     r (integer):
        Block size parameter.
     p (integer):
        Parallelization parameter.
        It must be no greater than :math:`(2^{32}-1)/(4r)`.
     num_keys (integer):
        The number of keys to derive. Every key is :data:`key_len` bytes long.
        By default, only 1 key is generated.
        The maximum cumulative length of all keys is :math:`(2^{32}-1)*32`
        (that is, 128TB).

    A good choice of parameters *(N, r , p)* was suggested
    by Colin Percival in his `presentation in 2009`__:

    - *(16384, 8, 1)* for interactive logins (<=100ms)
    - *(1048576, 8, 1)* for file encryption (<=5s)

    Return:
        A byte string or a tuple of byte strings.

    .. _scrypt: http://www.tarsnap.com/scrypt.html
    .. __: http://www.tarsnap.com/scrypt/scrypt.pdf
    .. __: https://tools.ietf.org/html/rfc7914
    .. __: http://www.tarsnap.com/scrypt/scrypt-slides.pdf
    """

    if 2**(bit_size(N) - 1) != N:
        raise ValueError("N must be a power of 2")
    if N >= 2**32:
        raise ValueError("N is too big")
    if p > ((2**32 - 1) * 32) // (128 * r):
        raise ValueError("p or r are too big")

    prf_hmac_sha256 = lambda p, s: HMAC.new(p, s, SHA256).digest()

    stage_1 = PBKDF2(password, salt, p * 128 * r, 1, prf=prf_hmac_sha256)

    scryptROMix = _raw_scrypt_lib.scryptROMix
    core = _raw_salsa20_lib.Salsa20_8_core

    # Parallelize into p flows
    data_out = []
    for flow in range(p):
        idx = flow * 128 * r
        buffer_out = create_string_buffer(128 * r)
        result = scryptROMix(stage_1[idx:idx + 128 * r], buffer_out,
                             c_size_t(128 * r), N, core)
        if result:
            raise ValueError("Error %X while running scrypt" % result)
        data_out += [get_raw_buffer(buffer_out)]

    dk = PBKDF2(password,
                b"".join(data_out),
                key_len * num_keys,
                1,
                prf=prf_hmac_sha256)

    if num_keys == 1:
        return dk

    kol = [
        dk[idx:idx + key_len] for idx in range(0, key_len * num_keys, key_len)
    ]
    return kol
示例#33
0
    def encrypt(self, plaintext, output=None):
        """Encrypt data with the key and the parameters set at initialization.

        A cipher object is stateful: once you have encrypted a message
        you cannot encrypt (or decrypt) another message using the same
        object.

        The data to encrypt can be broken up in two or
        more pieces and `encrypt` can be called multiple times.

        That is, the statement:

            >>> c.encrypt(a) + c.encrypt(b)

        is equivalent to:

             >>> c.encrypt(a+b)

        This function does not add any padding to the plaintext.

        :Parameters:
          plaintext : bytes/bytearray/memoryview
            The piece of data to encrypt.
            It can be of any length.
        :Keywords:
          output : bytearray/memoryview
            The location where the ciphertext must be written to.
            If ``None``, the ciphertext is returned.
        :Return:
          If ``output`` is ``None``, the ciphertext is returned as ``bytes``.
          Otherwise, ``None``.
        """

        if self.encrypt not in self._next:
            raise TypeError("encrypt() cannot be called after decrypt()")
        self._next = [self.encrypt]

        if output is None:
            ciphertext = create_string_buffer(len(plaintext))
        else:
            ciphertext = output

            if _is_immutable(output):
                raise TypeError(
                    "output must be a bytearray or a writeable memoryview")

            if len(plaintext) != len(output):
                raise ValueError(
                    "output must have the same length as the input"
                    "  (%d bytes)" % len(plaintext))

        result = raw_ctr_lib.CTR_encrypt(self._state.get(),
                                         c_uint8_ptr(plaintext),
                                         c_uint8_ptr(ciphertext),
                                         c_size_t(len(plaintext)))
        if result:
            if result == 0x60002:
                raise OverflowError("The counter has wrapped around in"
                                    " CTR mode")
            raise ValueError("Error %X while encrypting in CTR mode" % result)

        if output is None:
            return get_raw_buffer(ciphertext)
        else:
            return None