# Path: pycoind/util/pyscrypt/util.py
# def block_xor(source, source_start, dest, dest_start, length):
#     '''Performs xor on arrays source and dest, storing the result back in dest.'''
# 
#     for i in xrange(0, length):
#         dest[dest_start + i] = chr(ord(dest[dest_start + i]) ^ ord(source[source_start + i]))


import struct
from .util import block_xor
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.




def pbkdf2(password, salt, count, key_length, prf):
    '''Returns the result of the Password-Based Key Derivation Function 2.
      prf - a psuedorandom function

       See http://en.wikipedia.org/wiki/PBKDF2
    '''

    def f(block_number):
        '''The function "f".'''

        U = prf(password, salt + struct.pack('>L', block_number))

        if count > 1:
            U = [ c for c in U ]
            for i in xrange(2, 1 + count):

# Path: pycoind/util/pyscrypt/util.py
# def block_xor(source, source_start, dest, dest_start, length):
#     '''Performs xor on arrays source and dest, storing the result back in dest.'''
# 
#     for i in xrange(0, length):
#         dest[dest_start + i] = chr(ord(dest[dest_start + i]) ^ ord(source[source_start + i]))


# Path: pycoind/util/pyscrypt/pbkdf2.py
import struct
from .util import block_xor

#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.




def pbkdf2(password, salt, count, key_length, prf):
    '''Returns the result of the Password-Based Key Derivation Function 2.
      prf - a psuedorandom function

       See http://en.wikipedia.org/wiki/PBKDF2
    '''

    def f(block_number):
        '''The function "f".'''

        U = prf(password, salt + struct.pack('>L', block_number))

        if count > 1:
            U = [ c for c in U ]
            for i in xrange(2, 1 + count):

                block_xor(prf(password, ''.join(U)), 0, U, 0, len(U))