diff -pruN 0.8.0-0.3/appveyor/install.ps1 0.8.20-1/appveyor/install.ps1
--- 0.8.0-0.3/appveyor/install.ps1	1970-01-01 00:00:00.000000000 +0000
+++ 0.8.20-1/appveyor/install.ps1	2022-02-21 10:55:27.000000000 +0000
@@ -0,0 +1,229 @@
+# Sample script to install Python and pip under Windows
+# Authors: Olivier Grisel, Jonathan Helmus, Kyle Kastner, and Alex Willmer
+# License: CC0 1.0 Universal: http://creativecommons.org/publicdomain/zero/1.0/
+
+$MINICONDA_URL = "http://repo.continuum.io/miniconda/"
+$BASE_URL = "https://www.python.org/ftp/python/"
+$GET_PIP_URL = "https://bootstrap.pypa.io/get-pip.py"
+$GET_PIP_PATH = "C:\get-pip.py"
+
+$PYTHON_PRERELEASE_REGEX = @"
+(?x)
+(?<major>\d+)
+\.
+(?<minor>\d+)
+\.
+(?<micro>\d+)
+(?<prerelease>[a-z]{1,2}\d+)
+"@
+
+
+function Download ($filename, $url) {
+    $webclient = New-Object System.Net.WebClient
+
+    $basedir = $pwd.Path + "\"
+    $filepath = $basedir + $filename
+    if (Test-Path $filename) {
+        Write-Host "Reusing" $filepath
+        return $filepath
+    }
+
+    # Download and retry up to 3 times in case of network transient errors.
+    Write-Host "Downloading" $filename "from" $url
+    $retry_attempts = 2
+    for ($i = 0; $i -lt $retry_attempts; $i++) {
+        try {
+            $webclient.DownloadFile($url, $filepath)
+            break
+        }
+        Catch [Exception]{
+            Start-Sleep 1
+        }
+    }
+    if (Test-Path $filepath) {
+        Write-Host "File saved at" $filepath
+    } else {
+        # Retry once to get the error message if any at the last try
+        $webclient.DownloadFile($url, $filepath)
+    }
+    return $filepath
+}
+
+
+function ParsePythonVersion ($python_version) {
+    if ($python_version -match $PYTHON_PRERELEASE_REGEX) {
+        return ([int]$matches.major, [int]$matches.minor, [int]$matches.micro,
+                $matches.prerelease)
+    }
+    $version_obj = [version]$python_version
+    return ($version_obj.major, $version_obj.minor, $version_obj.build, "")
+}
+
+
+function DownloadPython ($python_version, $platform_suffix) {
+    $major, $minor, $micro, $prerelease = ParsePythonVersion $python_version
+
+    if (($major -le 2 -and $micro -eq 0) `
+        -or ($major -eq 3 -and $minor -le 2 -and $micro -eq 0) `
+        ) {
+        $dir = "$major.$minor"
+        $python_version = "$major.$minor$prerelease"
+    } else {
+        $dir = "$major.$minor.$micro"
+    }
+
+    if ($prerelease) {
+        if (($major -le 2) `
+            -or ($major -eq 3 -and $minor -eq 1) `
+            -or ($major -eq 3 -and $minor -eq 2) `
+            -or ($major -eq 3 -and $minor -eq 3) `
+            ) {
+            $dir = "$dir/prev"
+        }
+    }
+
+    if (($major -le 2) -or ($major -le 3 -and $minor -le 4)) {
+        $ext = "msi"
+        if ($platform_suffix) {
+            $platform_suffix = ".$platform_suffix"
+        }
+    } else {
+        $ext = "exe"
+        if ($platform_suffix) {
+            $platform_suffix = "-$platform_suffix"
+        }
+    }
+
+    $filename = "python-$python_version$platform_suffix.$ext"
+    $url = "$BASE_URL$dir/$filename"
+    $filepath = Download $filename $url
+    return $filepath
+}
+
+
+function InstallPython ($python_version, $architecture, $python_home) {
+    Write-Host "Installing Python" $python_version "for" $architecture "bit architecture to" $python_home
+    if (Test-Path $python_home) {
+        Write-Host $python_home "already exists, skipping."
+        return $false
+    }
+    if ($architecture -eq "32") {
+        $platform_suffix = ""
+    } else {
+        $platform_suffix = "amd64"
+    }
+    $installer_path = DownloadPython $python_version $platform_suffix
+    $installer_ext = [System.IO.Path]::GetExtension($installer_path)
+    Write-Host "Installing $installer_path to $python_home"
+    $install_log = $python_home + ".log"
+    if ($installer_ext -eq '.msi') {
+        InstallPythonMSI $installer_path $python_home $install_log
+    } else {
+        InstallPythonEXE $installer_path $python_home $install_log
+    }
+    if (Test-Path $python_home) {
+        Write-Host "Python $python_version ($architecture) installation complete"
+    } else {
+        Write-Host "Failed to install Python in $python_home"
+        Get-Content -Path $install_log
+        Exit 1
+    }
+}
+
+
+function InstallPythonEXE ($exepath, $python_home, $install_log) {
+    $install_args = "/quiet InstallAllUsers=1 TargetDir=$python_home"
+    RunCommand $exepath $install_args
+}
+
+
+function InstallPythonMSI ($msipath, $python_home, $install_log) {
+    $install_args = "/qn /log $install_log /i $msipath TARGETDIR=$python_home"
+    $uninstall_args = "/qn /x $msipath"
+    RunCommand "msiexec.exe" $install_args
+    if (-not(Test-Path $python_home)) {
+        Write-Host "Python seems to be installed else-where, reinstalling."
+        RunCommand "msiexec.exe" $uninstall_args
+        RunCommand "msiexec.exe" $install_args
+    }
+}
+
+function RunCommand ($command, $command_args) {
+    Write-Host $command $command_args
+    Start-Process -FilePath $command -ArgumentList $command_args -Wait -Passthru
+}
+
+
+function InstallPip ($python_home) {
+    $pip_path = $python_home + "\Scripts\pip.exe"
+    $python_path = $python_home + "\python.exe"
+    if (-not(Test-Path $pip_path)) {
+        Write-Host "Installing pip..."
+        $webclient = New-Object System.Net.WebClient
+        $webclient.DownloadFile($GET_PIP_URL, $GET_PIP_PATH)
+        Write-Host "Executing:" $python_path $GET_PIP_PATH
+        & $python_path $GET_PIP_PATH
+    } else {
+        Write-Host "pip already installed."
+    }
+}
+
+
+function DownloadMiniconda ($python_version, $platform_suffix) {
+    if ($python_version -eq "3.4") {
+        $filename = "Miniconda3-3.5.5-Windows-" + $platform_suffix + ".exe"
+    } else {
+        $filename = "Miniconda-3.5.5-Windows-" + $platform_suffix + ".exe"
+    }
+    $url = $MINICONDA_URL + $filename
+    $filepath = Download $filename $url
+    return $filepath
+}
+
+
+function InstallMiniconda ($python_version, $architecture, $python_home) {
+    Write-Host "Installing Python" $python_version "for" $architecture "bit architecture to" $python_home
+    if (Test-Path $python_home) {
+        Write-Host $python_home "already exists, skipping."
+        return $false
+    }
+    if ($architecture -eq "32") {
+        $platform_suffix = "x86"
+    } else {
+        $platform_suffix = "x86_64"
+    }
+    $filepath = DownloadMiniconda $python_version $platform_suffix
+    Write-Host "Installing" $filepath "to" $python_home
+    $install_log = $python_home + ".log"
+    $args = "/S /D=$python_home"
+    Write-Host $filepath $args
+    Start-Process -FilePath $filepath -ArgumentList $args -Wait -Passthru
+    if (Test-Path $python_home) {
+        Write-Host "Python $python_version ($architecture) installation complete"
+    } else {
+        Write-Host "Failed to install Python in $python_home"
+        Get-Content -Path $install_log
+        Exit 1
+    }
+}
+
+
+function InstallMinicondaPip ($python_home) {
+    $pip_path = $python_home + "\Scripts\pip.exe"
+    $conda_path = $python_home + "\Scripts\conda.exe"
+    if (-not(Test-Path $pip_path)) {
+        Write-Host "Installing pip..."
+        $args = "install --yes pip"
+        Write-Host $conda_path $args
+        Start-Process -FilePath "$conda_path" -ArgumentList $args -Wait -Passthru
+    } else {
+        Write-Host "pip already installed."
+    }
+}
+
+function main () {
+    InstallPython $env:PYTHON_VERSION $env:PYTHON_ARCH $env:PYTHON
+    InstallPip $env:PYTHON
+}
+
+main
diff -pruN 0.8.0-0.3/appveyor/run_with_env.cmd 0.8.20-1/appveyor/run_with_env.cmd
--- 0.8.0-0.3/appveyor/run_with_env.cmd	1970-01-01 00:00:00.000000000 +0000
+++ 0.8.20-1/appveyor/run_with_env.cmd	2022-02-21 10:55:27.000000000 +0000
@@ -0,0 +1,88 @@
+:: To build extensions for 64 bit Python 3, we need to configure environment
+:: variables to use the MSVC 2010 C++ compilers from GRMSDKX_EN_DVD.iso of:
+:: MS Windows SDK for Windows 7 and .NET Framework 4 (SDK v7.1)
+::
+:: To build extensions for 64 bit Python 2, we need to configure environment
+:: variables to use the MSVC 2008 C++ compilers from GRMSDKX_EN_DVD.iso of:
+:: MS Windows SDK for Windows 7 and .NET Framework 3.5 (SDK v7.0)
+::
+:: 32 bit builds, and 64-bit builds for 3.5 and beyond, do not require specific
+:: environment configurations.
+::
+:: Note: this script needs to be run with the /E:ON and /V:ON flags for the
+:: cmd interpreter, at least for (SDK v7.0)
+::
+:: More details at:
+:: https://github.com/cython/cython/wiki/64BitCythonExtensionsOnWindows
+:: http://stackoverflow.com/a/13751649/163740
+::
+:: Author: Olivier Grisel
+:: License: CC0 1.0 Universal: http://creativecommons.org/publicdomain/zero/1.0/
+::
+:: Notes about batch files for Python people:
+::
+:: Quotes in values are literally part of the values:
+::      SET FOO="bar"
+:: FOO is now five characters long: " b a r "
+:: If you don't want quotes, don't include them on the right-hand side.
+::
+:: The CALL lines at the end of this file look redundant, but if you move them
+:: outside of the IF clauses, they do not run properly in the SET_SDK_64==Y
+:: case, I don't know why.
+@ECHO OFF
+
+SET COMMAND_TO_RUN=%*
+SET WIN_SDK_ROOT=C:\Program Files\Microsoft SDKs\Windows
+SET WIN_WDK=c:\Program Files (x86)\Windows Kits\10\Include\wdf
+
+:: Extract the major and minor versions, and allow for the minor version to be
+:: more than 9.  This requires the version number to have two dots in it.
+SET MAJOR_PYTHON_VERSION=%PYTHON_VERSION:~0,1%
+IF "%PYTHON_VERSION:~3,1%" == "." (
+    SET MINOR_PYTHON_VERSION=%PYTHON_VERSION:~2,1%
+) ELSE (
+    SET MINOR_PYTHON_VERSION=%PYTHON_VERSION:~2,2%
+)
+
+:: Based on the Python version, determine what SDK version to use, and whether
+:: to set the SDK for 64-bit.
+IF %MAJOR_PYTHON_VERSION% == 2 (
+    SET WINDOWS_SDK_VERSION="v7.0"
+    SET SET_SDK_64=Y
+) ELSE (
+    IF %MAJOR_PYTHON_VERSION% == 3 (
+        SET WINDOWS_SDK_VERSION="v7.1"
+        IF %MINOR_PYTHON_VERSION% LEQ 4 (
+            SET SET_SDK_64=Y
+        ) ELSE (
+            SET SET_SDK_64=N
+            IF EXIST "%WIN_WDK%" (
+                :: See: https://connect.microsoft.com/VisualStudio/feedback/details/1610302/
+                REN "%WIN_WDK%" 0wdf
+            )
+        )
+    ) ELSE (
+        ECHO Unsupported Python version: "%MAJOR_PYTHON_VERSION%"
+        EXIT 1
+    )
+)
+
+IF %PYTHON_ARCH% == 64 (
+    IF %SET_SDK_64% == Y (
+        ECHO Configuring Windows SDK %WINDOWS_SDK_VERSION% for Python %MAJOR_PYTHON_VERSION% on a 64 bit architecture
+        SET DISTUTILS_USE_SDK=1
+        SET MSSdk=1
+        "%WIN_SDK_ROOT%\%WINDOWS_SDK_VERSION%\Setup\WindowsSdkVer.exe" -q -version:%WINDOWS_SDK_VERSION%
+        "%WIN_SDK_ROOT%\%WINDOWS_SDK_VERSION%\Bin\SetEnv.cmd" /x64 /release
+        ECHO Executing: %COMMAND_TO_RUN%
+        call %COMMAND_TO_RUN% || EXIT 1
+    ) ELSE (
+        ECHO Using default MSVC build environment for 64 bit architecture
+        ECHO Executing: %COMMAND_TO_RUN%
+        call %COMMAND_TO_RUN% || EXIT 1
+    )
+) ELSE (
+    ECHO Using default MSVC build environment for 32 bit architecture
+    ECHO Executing: %COMMAND_TO_RUN%
+    call %COMMAND_TO_RUN% || EXIT 1
+)
diff -pruN 0.8.0-0.3/appveyor.yml 0.8.20-1/appveyor.yml
--- 0.8.0-0.3/appveyor.yml	1970-01-01 00:00:00.000000000 +0000
+++ 0.8.20-1/appveyor.yml	2022-02-21 10:55:27.000000000 +0000
@@ -0,0 +1,108 @@
+# Based on https://github.com/ogrisel/python-appveyor-demo/blob/master/appveyor.yml
+image: Visual Studio 2019
+
+environment:
+  global:
+    # SDK v7.0 MSVC Express 2008's SetEnv.cmd script will fail if the
+    # /E:ON and /V:ON options are not enabled in the batch script intepreter
+    # See: http://stackoverflow.com/a/13751649/163740
+    CMD_IN_ENV: "cmd /E:ON /V:ON /C .\\appveyor\\run_with_env.cmd"
+
+  matrix:
+
+    - PYTHON: "C:\\Python36"
+      PYTHON_VERSION: "3.6.3"
+      PYTHON_ARCH: "32"
+
+    - PYTHON: "C:\\Python36-x64"
+      PYTHON_VERSION: "3.6.3"
+      PYTHON_ARCH: "64"
+
+    - PYTHON: "C:\\Python37"
+      PYTHON_VERSION: "3.7"
+      PYTHON_ARCH: "32"
+
+    - PYTHON: "C:\\Python37-x64"
+      PYTHON_VERSION: "3.7"
+      PYTHON_ARCH: "64"
+
+    - PYTHON: "C:\\Python38"
+      PYTHON_VERSION: "3.8"
+      PYTHON_ARCH: "32"
+
+    - PYTHON: "C:\\Python38-x64"
+      PYTHON_VERSION: "3.8"
+      PYTHON_ARCH: "64"
+
+    - PYTHON: "C:\\Python39"
+      PYTHON_VERSION: "3.9"
+      PYTHON_ARCH: "32"
+
+    - PYTHON: "C:\\Python39-x64"
+      PYTHON_VERSION: "3.9"
+      PYTHON_ARCH: "64"
+install:
+  # If there is a newer build queued for the same PR, cancel this one.
+  # The AppVeyor 'rollout builds' option is supposed to serve the same
+  # purpose but it is problematic because it tends to cancel builds pushed
+  # directly to master instead of just PR builds (or the converse).
+  # credits: JuliaLang developers.
+  - ps: if ($env:APPVEYOR_PULL_REQUEST_NUMBER -and $env:APPVEYOR_BUILD_NUMBER -ne ((Invoke-RestMethod `
+        https://ci.appveyor.com/api/projects/$env:APPVEYOR_ACCOUNT_NAME/$env:APPVEYOR_PROJECT_SLUG/history?recordsNumber=50).builds | `
+        Where-Object pullRequestId -eq $env:APPVEYOR_PULL_REQUEST_NUMBER)[0].buildNumber) { `
+          throw "There are newer queued builds for this pull request, failing early." }
+  - ECHO "Filesystem root:"
+  - ps: "ls \"C:/\""
+
+  # Install Python (from the official .msi of http://python.org) and pip when
+  # not already installed.
+  - ps: if (-not(Test-Path($env:PYTHON))) { & appveyor\install.ps1 }
+
+  # Prepend newly installed Python to the PATH of this build (this cannot be
+  # done from inside the powershell script as it would require to restart
+  # the parent CMD process).
+  - "SET PATH=%PYTHON%;%PYTHON%\\Scripts;%PATH%"
+
+  # Check that we have the expected version and architecture for Python
+  - "python --version"
+  - "python -c \"import struct; print(struct.calcsize('P') * 8)\""
+
+  # Upgrade to the latest version of pip to avoid it displaying warnings
+  # about it being out of date.
+  - "python -m pip install -r dev-requirements.txt"
+  - "python -m pip install --disable-pip-version-check --user --upgrade pip"
+
+build_script:
+  # Build the compiled extension
+  - "%CMD_IN_ENV% python setup.py build"
+
+test_script:
+  # Run the project tests
+  - "%CMD_IN_ENV% python setup.py test"
+
+after_test:
+  # If tests are successful, create binary packages for the project.
+  - "%CMD_IN_ENV% pip install wheel"
+  - "%CMD_IN_ENV% python setup.py bdist_wheel"
+  - "%CMD_IN_ENV% python setup.py bdist_wininst"
+  - "%CMD_IN_ENV% python setup.py bdist_msi"
+  - ps: "ls dist"
+
+artifacts:
+  # Archive the generated packages in the ci.appveyor.com build report.
+  - path: dist\*
+
+deploy:
+  provider: GitHub
+  auth_token:
+    secure: 0/vpfUG++7riJDu6Zc0smoTJJJm1t9/qiOzY/IR5vtaFNZNVYmRbEt8jS8LxpnFW
+  artifact: dist\*
+  #force_update: true
+  #draft: true
+  #prerelease: true
+  # description: "Python Wheels for py-scrypt"
+  #tag: $(APPVEYOR_REPO_TAG_NAME) # will not work until tag is pushed
+  on:
+#    configuration: Release    # Debug contains non-redist MS DLLs
+    APPVEYOR_REPO_TAG: true   # deploy on tag push only
+    branch: master   # release from master branch only
\ No newline at end of file
diff -pruN 0.8.0-0.3/debian/changelog 0.8.20-1/debian/changelog
--- 0.8.0-0.3/debian/changelog	2019-12-07 18:57:05.000000000 +0000
+++ 0.8.20-1/debian/changelog	2022-03-30 02:10:52.000000000 +0000
@@ -1,3 +1,46 @@
+python-scrypt (0.8.20-1) unstable; urgency=medium
+
+  * New upstream release.
+  * Take over package maintenance via ITS process. (Closes: #1007801) 
+
+ -- Boyuan Yang <byang@debian.org>  Tue, 29 Mar 2022 22:10:52 -0400
+
+python-scrypt (0.8.19-0.1) unstable; urgency=medium
+
+  * Non-maintainer upload.
+  * New upstream release.
+  * debian/control:
+    + Add GitHub homepage.
+  * debian/rules: Enable full hardening.
+  * debian/watch: Switch to monitor GitHub upstream instead.
+  * debian/gbp.conf: Added to reflect packaging repo.
+  * debian/copyright: Minor update.
+  * debian/python3-scrypt.docs: Also install README.rst.
+
+ -- Boyuan Yang <byang@debian.org>  Sun, 23 Jan 2022 21:05:35 -0500
+
+python-scrypt (0.8.0-0.4) unstable; urgency=low
+
+  * Non-maintainer upload.
+  * Rebuild after Debian 11 release.
+
+  [ Debian Janitor ]
+  * Trim trailing whitespace.
+  * Use secure copyright file specification URI.
+  * Add debian/watch file, using pypi.
+
+  [ Ondřej Nový ]
+  * d/control: Update Vcs-* fields with new Debian Python Team Salsa
+    layout.
+
+  [ Boyuan Yang ]
+  * Update standards version to 4.6.0, no changes needed.
+  * Bump debhelper compat to v13.
+  * Add dependency to libpython3-all-dev for cross compilation.
+    (Closes: #990064)
+
+ -- Boyuan Yang <byang@debian.org>  Fri, 20 Aug 2021 00:07:28 -0400
+
 python-scrypt (0.8.0-0.3) unstable; urgency=medium
 
   * Non-maintainer upload.
diff -pruN 0.8.0-0.3/debian/control 0.8.20-1/debian/control
--- 0.8.0-0.3/debian/control	2019-12-07 18:56:10.000000000 +0000
+++ 0.8.20-1/debian/control	2022-03-30 02:10:52.000000000 +0000
@@ -1,16 +1,20 @@
 Source: python-scrypt
-Maintainer: Micah Anderson <micah@debian.org>
 Section: python
 Priority: optional
+Maintainer: Debian Python Team <team+python@tracker.debian.org>
+Uploaders:
+ Boyuan Yang <byang@debian.org>,
 Build-Depends:
- debhelper-compat (= 12),
- dh-python,
+ debhelper-compat (= 13),
+ dh-sequence-python3,
  libssl-dev,
+ libpython3-all-dev,
  python3-all-dev:any,
  python3-setuptools,
-Standards-Version: 4.4.1
-Vcs-Git: https://salsa.debian.org/python-team/modules/python-scrypt.git
-Vcs-Browser: https://salsa.debian.org/python-team/modules/python-scrypt
+Standards-Version: 4.6.0
+Homepage: https://github.com/holgern/py-scrypt
+Vcs-Git: https://salsa.debian.org/python-team/packages/python-scrypt.git
+Vcs-Browser: https://salsa.debian.org/python-team/packages/python-scrypt
 
 Package: python3-scrypt
 Architecture: any
@@ -19,7 +23,7 @@ Depends:
  ${python3:Depends},
  ${shlibs:Depends}
 Description: bindings for the scrypt key derivation function library - Python 3.x
- This is a set of Python bindings for the scrypt key derivation function. 
+ This is a set of Python bindings for the scrypt key derivation function.
  .
  Scrypt is useful when encrypting password as it is possible to specify a
  minimum amount of time to use when encrypting and decrypting. If, for
diff -pruN 0.8.0-0.3/debian/copyright 0.8.20-1/debian/copyright
--- 0.8.0-0.3/debian/copyright	2019-12-07 18:52:46.000000000 +0000
+++ 0.8.20-1/debian/copyright	2022-01-24 02:07:39.000000000 +0000
@@ -1,4 +1,4 @@
-Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
+Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
 Upstream-Name: scrypt
 Upstream-Contact: mhallin@gmail.com
 Source: <http://bitbucket.org/mhallin/py-scrypt>
@@ -30,14 +30,349 @@ License: BSD-2-Clause
  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  SUCH DAMAGE.
 
-Files: scrypt-1.1.6/*
+Files: scrypt-1.2.1/*
 Copyright: Copyright 2005,2007-2009 Colin Percival
 License: BSD-2-Clause
 
 Files: debian/*
 Copyright: Copyright 2013 Micah Anderson <micah@leap.se>
 License: GPL-3+
+
+Files: scrypt-windows-stubs/gettimeofday.c
+Copyright:
+ 2003 SRA, Inc.
+ 2003 SKC, Inc.
+License: PostgreSQL
+
+Files: scrypt-windows-stubs/include/getopt.h
+Copyright:
+ 2002-2003 Mark K. Kim
+License: BSD-3-Clause
+
+Files:
+ scrypt-windows-stubs/include/inttypes.h
+ scrypt-windows-stubs/include/stdint.h
+Copyright:
+ 2006-2008 Alexander Chemeris
+License: BSD-3-Clause
+
+Files: scrypt-windows-stubs/include/unistd.h
+Copyright:
+ 2009 AShelly
+License: CC-BY-SA-2.5
+Comment:
+ http://stackoverflow.com/a/826027
+
+License: BSD-3-Clause
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+ .
+   1. Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimer.
+ .
+   2. Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in the
+      documentation and/or other materials provided with the distribution.
+ .
+   3. The name of the author may be used to endorse or promote products
+      derived from this software without specific prior written permission.
+ .
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+License: CC-BY-SA-2.5
+ CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
+ LEGAL SERVICES. DISTRIBUTION OF THIS LICENSE DOES NOT CREATE AN
+ ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS INFORMATION
+ ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES REGARDING THE
+ INFORMATION PROVIDED, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
+ ITS USE.
+ .
+ License
+ .
+ THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE
+ COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY
+ COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS
+ AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED.
+ .
+ BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE
+ TO BE BOUND BY THE TERMS OF THIS LICENSE. THE LICENSOR GRANTS YOU THE
+ RIGHTS CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS
+ AND CONDITIONS.
+ .
+ 1. Definitions
+ .
+ a. "Collective Work" means a work, such as a periodical issue, anthology
+ or encyclopedia, in which the Work in its entirety in unmodified form,
+ along with a number of other contributions, constituting separate and
+ independent works in themselves, are assembled into a collective whole.
+ A work that constitutes a Collective Work will not be considered a
+ Derivative Work (as defined below) for the purposes of this License.
+ .
+ b. "Derivative Work" means a work based upon the Work or upon the Work
+ and other pre-existing works, such as a translation, musical
+ arrangement, dramatization, fictionalization, motion picture version,
+ sound recording, art reproduction, abridgment, condensation, or any
+ other form in which the Work may be recast, transformed, or adapted,
+ except that a work that constitutes a Collective Work will not be
+ considered a Derivative Work for the purpose of this License. For the
+ avoidance of doubt, where the Work is a musical composition or sound
+ recording, the synchronization of the Work in timed-relation with a
+ moving image ("synching") will be considered a Derivative Work for the
+ purpose of this License.
+ .
+ c. "Licensor" means the individual or entity that offers the Work under
+ the terms of this License.
+ .
+ d. "Original Author" means the individual or entity who created the
+ Work.
+ .
+ e. "Work" means the copyrightable work of authorship offered under the
+ terms of this License.
+ .
+ f. "You" means an individual or entity exercising rights under this
+ License who has not previously violated the terms of this License with
+ respect to the Work, or who has received express permission from the
+ Licensor to exercise rights under this License despite a previous
+ violation.
+ .
+ g. "License Elements" means the following high-level license attributes
+ as selected by Licensor and indicated in the title of this License:
+ Attribution, ShareAlike.
+ .
+ 2. Fair Use Rights. Nothing in this license is intended to reduce,
+ limit, or restrict any rights arising from fair use, first sale or other
+ limitations on the exclusive rights of the copyright owner under
+ copyright law or other applicable laws.
+ .
+ 3. License Grant. Subject to the terms and conditions of this License,
+ Licensor hereby grants You a worldwide, royalty-free, non-exclusive,
+ perpetual (for the duration of the applicable copyright) license to
+ exercise the rights in the Work as stated below:
+ .
+ a. to reproduce the Work, to incorporate the Work into one or more
+ Collective Works, and to reproduce the Work as incorporated in the
+ Collective Works;
+ .
+ b. to create and reproduce Derivative Works;
+ .
+ c. to distribute copies or phonorecords of, display publicly, perform
+ publicly, and perform publicly by means of a digital audio transmission
+ the Work including as incorporated in Collective Works;
+ .
+ d. to distribute copies or phonorecords of, display publicly, perform
+ publicly, and perform publicly by means of a digital audio transmission
+ Derivative Works.
+ .
+ e. For the avoidance of doubt, where the work is a musical composition:
+ .
+ i. Performance Royalties Under Blanket Licenses. Licensor waives the
+ exclusive right to collect, whether individually or via a performance
+ rights society (e.g. ASCAP, BMI, SESAC), royalties for the public
+ performance or public digital performance (e.g. webcast) of the Work.
+ .
+ ii. Mechanical Rights and Statutory Royalties. Licensor waives the
+ exclusive right to collect, whether individually or via a music rights
+ society or designated agent (e.g. Harry Fox Agency), royalties for any
+ phonorecord You create from the Work ("cover version") and distribute,
+ subject to the compulsory license created by 17 USC Section 115 of the
+ US Copyright Act (or the equivalent in other jurisdictions).
+ .
+ f. Webcasting Rights and Statutory Royalties. For the avoidance of
+ doubt, where the Work is a sound recording, Licensor waives the
+ exclusive right to collect, whether individually or via a
+ performance-rights society (e.g. SoundExchange), royalties for the
+ public digital performance (e.g. webcast) of the Work, subject to the
+ compulsory license created by 17 USC Section 114 of the US Copyright Act
+ (or the equivalent in other jurisdictions).
+ .
+ The above rights may be exercised in all media and formats whether now
+ known or hereafter devised. The above rights include the right to make
+ such modifications as are technically necessary to exercise the rights
+ in other media and formats. All rights not expressly granted by Licensor
+ are hereby reserved.
+ .
+ 4. Restrictions. The license granted in Section 3 above is expressly
+ made subject to and limited by the following restrictions:
+ .
+ a. You may distribute, publicly display, publicly perform, or publicly
+ digitally perform the Work only under the terms of this License, and You
+ must include a copy of, or the Uniform Resource Identifier for, this
+ License with every copy or phonorecord of the Work You distribute,
+ publicly display, publicly perform, or publicly digitally perform. You
+ may not offer or impose any terms on the Work that alter or restrict the
+ terms of this License or the recipients' exercise of the rights granted
+ hereunder. You may not sublicense the Work. You must keep intact all
+ notices that refer to this License and to the disclaimer of warranties.
+ You may not distribute, publicly display, publicly perform, or publicly
+ digitally perform the Work with any technological measures that control
+ access or use of the Work in a manner inconsistent with the terms of
+ this License Agreement. The above applies to the Work as incorporated in
+ a Collective Work, but this does not require the Collective Work apart
+ from the Work itself to be made subject to the terms of this License. If
+ You create a Collective Work, upon notice from any Licensor You must, to
+ the extent practicable, remove from the Collective Work any credit as
+ required by clause 4(c), as requested. If You create a Derivative Work,
+ upon notice from any Licensor You must, to the extent practicable,
+ remove from the Derivative Work any credit as required by clause 4(c),
+ as requested.
+ .
+ b. You may distribute, publicly display, publicly perform, or publicly
+ digitally perform a Derivative Work only under the terms of this
+ License, a later version of this License with the same License Elements
+ as this License, or a Creative Commons iCommons license that contains
+ the same License Elements as this License (e.g. Attribution-ShareAlike
+ 2.5 Japan). You must include a copy of, or the Uniform Resource
+ Identifier for, this License or other license specified in the previous
+ sentence with every copy or phonorecord of each Derivative Work You
+ distribute, publicly display, publicly perform, or publicly digitally
+ perform. You may not offer or impose any terms on the Derivative Works
+ that alter or restrict the terms of this License or the recipients'
+ exercise of the rights granted hereunder, and You must keep intact all
+ notices that refer to this License and to the disclaimer of warranties.
+ You may not distribute, publicly display, publicly perform, or publicly
+ digitally perform the Derivative Work with any technological measures
+ that control access or use of the Work in a manner inconsistent with the
+ terms of this License Agreement. The above applies to the Derivative
+ Work as incorporated in a Collective Work, but this does not require the
+ Collective Work apart from the Derivative Work itself to be made subject
+ to the terms of this License.
+ .
+ c. If you distribute, publicly display, publicly perform, or publicly
+ digitally perform the Work or any Derivative Works or Collective Works,
+ You must keep intact all copyright notices for the Work and provide,
+ reasonable to the medium or means You are utilizing: (i) the name of the
+ Original Author (or pseudonym, if applicable) if supplied, and/or (ii)
+ if the Original Author and/or Licensor designate another party or
+ parties (e.g. a sponsor institute, publishing entity, journal) for
+ attribution in Licensor's copyright notice, terms of service or by other
+ reasonable means, the name of such party or parties; the title of the
+ Work if supplied; to the extent reasonably practicable, the Uniform
+ Resource Identifier, if any, that Licensor specifies to be associated
+ with the Work, unless such URI does not refer to the copyright notice or
+ licensing information for the Work; and in the case of a Derivative
+ Work, a credit identifying the use of the Work in the Derivative Work
+ (e.g., "French translation of the Work by Original Author," or
+ "Screenplay based on original Work by Original Author"). Such credit may
+ be implemented in any reasonable manner; provided, however, that in the
+ case of a Derivative Work or Collective Work, at a minimum such credit
+ will appear where any other comparable authorship credit appears and in
+ a manner at least as prominent as such other comparable authorship
+ credit.
+ .
+ 5. Representations, Warranties and Disclaimer
+ .
+ UNLESS OTHERWISE AGREED TO BY THE PARTIES IN WRITING, LICENSOR OFFERS
+ THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND
+ CONCERNING THE MATERIALS, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE,
+ INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY,
+ FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF
+ LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS,
+ WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE
+ EXCLUSION OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU.
+ .
+ 6. Limitation on Liability. EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE
+ LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR
+ ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES
+ ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF LICENSOR HAS
+ BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ .
+ 7. Termination
+ .
+ a. This License and the rights granted hereunder will terminate
+ automatically upon any breach by You of the terms of this License.
+ Individuals or entities who have received Derivative Works or Collective
+ Works from You under this License, however, will not have their licenses
+ terminated provided such individuals or entities remain in full
+ compliance with those licenses. Sections 1, 2, 5, 6, 7, and 8 will
+ survive any termination of this License.
+ .
+ b. Subject to the above terms and conditions, the license granted here
+ is perpetual (for the duration of the applicable copyright in the Work).
+ Notwithstanding the above, Licensor reserves the right to release the
+ Work under different license terms or to stop distributing the Work at
+ any time; provided, however that any such election will not serve to
+ withdraw this License (or any other license that has been, or is
+ required to be, granted under the terms of this License), and this
+ License will continue in full force and effect unless terminated as
+ stated above.
+ .
+ 8. Miscellaneous
+ .
+ a. Each time You distribute or publicly digitally perform the Work or a
+ Collective Work, the Licensor offers to the recipient a license to the
+ Work on the same terms and conditions as the license granted to You
+ under this License.
+ .
+ b. Each time You distribute or publicly digitally perform a Derivative
+ Work, Licensor offers to the recipient a license to the original Work on
+ the same terms and conditions as the license granted to You under this
+ License.
+ .
+ c. If any provision of this License is invalid or unenforceable under
+ applicable law, it shall not affect the validity or enforceability of
+ the remainder of the terms of this License, and without further action
+ by the parties to this agreement, such provision shall be reformed to
+ the minimum extent necessary to make such provision valid and
+ enforceable.
+ .
+ d. No term or provision of this License shall be deemed waived and no
+ breach consented to unless such waiver or consent shall be in writing
+ and signed by the party to be charged with such waiver or consent.
+ .
+ e. This License constitutes the entire agreement between the parties
+ with respect to the Work licensed here. There are no understandings,
+ agreements or representations with respect to the Work not specified
+ here. Licensor shall not be bound by any additional provisions that may
+ appear in any communication from You. This License may not be modified
+ without the mutual written agreement of the Licensor and You.
+ .
+ Creative Commons is not a party to this License, and makes no warranty
+ whatsoever in connection with the Work. Creative Commons will not be
+ liable to You or any party on any legal theory for any damages
+ whatsoever, including without limitation any general, special,
+ incidental or consequential damages arising in connection to this
+ license. Notwithstanding the foregoing two (2) sentences, if Creative
+ Commons has expressly identified itself as the Licensor hereunder, it
+ shall have all rights and obligations of Licensor.
+ .
+ Except for the limited purpose of indicating to the public that the Work
+ is licensed under the CCPL, neither party will use the trademark
+ "Creative Commons" or any related trademark or logo of Creative Commons
+ without the prior written consent of Creative Commons. Any permitted use
+ will be in compliance with Creative Commons' then-current trademark
+ usage guidelines, as may be published on its website or otherwise made
+ available upon request from time to time.
+ .
+ Creative Commons may be contacted at http://creativecommons.org/.
+
+License: PostgreSQL
+ Permission to use, copy, modify, and distribute this software and
+ its documentation for any purpose, without fee, and without a
+ written agreement is hereby granted, provided that the above
+ copyright notice and this paragraph and the following two
+ paragraphs appear in all copies.
+ .
+ IN NO EVENT SHALL THE AUTHOR BE LIABLE TO ANY PARTY FOR DIRECT,
+ INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING
+ LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS
+ DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED
+ OF THE POSSIBILITY OF SUCH DAMAGE.
+ .
+ THE AUTHOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS
+ IS" BASIS, AND THE AUTHOR HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE,
+ SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  
 License: GPL-3+
- On Debian systems, the complete text of the GNU General
- Public License can be found in `/usr/share/common-licenses/GPL'.
+ On Debian systems, the complete text of the GNU General Public License
+ version 3 can be found in `/usr/share/common-licenses/GPL-3'.
diff -pruN 0.8.0-0.3/debian/gbp.conf 0.8.20-1/debian/gbp.conf
--- 0.8.0-0.3/debian/gbp.conf	1970-01-01 00:00:00.000000000 +0000
+++ 0.8.20-1/debian/gbp.conf	2022-03-30 02:10:52.000000000 +0000
@@ -0,0 +1,4 @@
+[DEFAULT]
+debian-branch = debian/master
+upstream-tag = upstream/%(version)s
+pristine-tar = True
diff -pruN 0.8.0-0.3/debian/python3-scrypt.docs 0.8.20-1/debian/python3-scrypt.docs
--- 0.8.0-0.3/debian/python3-scrypt.docs	1970-01-01 00:00:00.000000000 +0000
+++ 0.8.20-1/debian/python3-scrypt.docs	2022-01-24 02:05:28.000000000 +0000
@@ -0,0 +1 @@
+README.rst
diff -pruN 0.8.0-0.3/debian/rules 0.8.20-1/debian/rules
--- 0.8.0-0.3/debian/rules	2019-12-07 18:53:17.000000000 +0000
+++ 0.8.20-1/debian/rules	2022-01-24 01:45:56.000000000 +0000
@@ -1,7 +1,13 @@
 #!/usr/bin/make -f
+# -*- makefile -*-
+# Uncomment this to turn on verbose mode.
+# export DH_VERBOSE=1
+
+# see FEATURE AREAS in dpkg-buildflags(1)
+export DEB_BUILD_MAINT_OPTIONS = hardening=+all
 
 %:
-	dh $@ --with python3 --buildsystem=pybuild
+	dh $@ --buildsystem=pybuild
 
 override_dh_auto_test:
 	:  # TODO: skip tests, they were never run before anyway
diff -pruN 0.8.0-0.3/debian/watch 0.8.20-1/debian/watch
--- 0.8.0-0.3/debian/watch	1970-01-01 00:00:00.000000000 +0000
+++ 0.8.20-1/debian/watch	2022-01-24 01:42:24.000000000 +0000
@@ -0,0 +1,4 @@
+version=4
+opts="filenamemangle=s%(?:.*?)?v?(\d[\d.]*@ARCHIVE_EXT@)%@PACKAGE@-$1%" \
+ https://github.com/holgern/py-scrypt/tags \
+ (?:.*?/)?v?@ANY_VERSION@@ARCHIVE_EXT@
diff -pruN 0.8.0-0.3/dev-requirements.txt 0.8.20-1/dev-requirements.txt
--- 0.8.0-0.3/dev-requirements.txt	1970-01-01 00:00:00.000000000 +0000
+++ 0.8.20-1/dev-requirements.txt	2022-02-21 10:55:27.000000000 +0000
@@ -0,0 +1,3 @@
+tox
+nose
+pytest
\ No newline at end of file
diff -pruN 0.8.0-0.3/.flake8 0.8.20-1/.flake8
--- 0.8.0-0.3/.flake8	1970-01-01 00:00:00.000000000 +0000
+++ 0.8.20-1/.flake8	2022-02-21 10:55:27.000000000 +0000
@@ -0,0 +1,8 @@
+[flake8]
+ignore =
+    # indentation is not a multiple of four,
+    E111,E114,
+    # visually indented line with same indent as next logical line,
+    E129
+
+max-line-length=80
diff -pruN 0.8.0-0.3/.github/workflows/wheels_arm64.yml 0.8.20-1/.github/workflows/wheels_arm64.yml
--- 0.8.0-0.3/.github/workflows/wheels_arm64.yml	1970-01-01 00:00:00.000000000 +0000
+++ 0.8.20-1/.github/workflows/wheels_arm64.yml	2022-02-21 10:55:27.000000000 +0000
@@ -0,0 +1,36 @@
+name: Build wheel on arm
+on: [push]
+env:
+  CIBW_BUILD_VERBOSITY: 1
+  CIBW_ARCHS: "auto64"
+  CIBW_TEST_REQUIRES: pytest
+  CIBW_TEST_COMMAND: "pytest --pyargs scrypt"
+jobs:
+
+  build_aarch64_wheels:
+    name: Build wheels manylinux_aarch64
+    runs-on: ubuntu-latest
+    strategy:
+      matrix:
+        python: [36, 37, 38, 39]
+        include:
+          - os: ubuntu-latest
+            arch: aarch64
+            platform_id: manylinux_aarch64
+    steps:
+      - uses: actions/checkout@v2
+
+      - name: Set up QEMU
+        uses: docker/setup-qemu-action@v1
+
+      - name: Install cibuildwheel
+        run: python -m pip install cibuildwheel
+
+      - name: Build wheels
+        run: python -m cibuildwheel --output-dir wheelhouse
+        env:
+          CIBW_ARCHS_LINUX: ${{matrix.arch}}
+          CIBW_BUILD: cp${{ matrix.python }}-${{ matrix.platform_id }}
+      - uses: actions/upload-artifact@v2
+        with:
+          path: wheelhouse/*.whl
\ No newline at end of file
diff -pruN 0.8.0-0.3/.github/workflows/wheels_linux.yml 0.8.20-1/.github/workflows/wheels_linux.yml
--- 0.8.0-0.3/.github/workflows/wheels_linux.yml	1970-01-01 00:00:00.000000000 +0000
+++ 0.8.20-1/.github/workflows/wheels_linux.yml	2022-02-21 10:55:27.000000000 +0000
@@ -0,0 +1,30 @@
+name: Build wheel on linux
+on: [push]
+env:
+  CIBW_BUILD_VERBOSITY: 1
+  CIBW_TEST_REQUIRES: pytest
+  CIBW_TEST_COMMAND: "pytest --pyargs scrypt"
+jobs:
+  build_wheels:
+    name: Build wheels on ubuntu-latest
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v2
+
+      # Used to host cibuildwheel
+      - uses: actions/setup-python@v2
+
+      - name: Install cibuildwheel
+        run: python -m pip install cibuildwheel
+
+      - name: Build wheels
+        run: python -m cibuildwheel --output-dir wheelhouse
+        env:
+          # Disable explicitly python 3.11 and building PyPy wheels
+          CIBW_SKIP: cp311-* pp*
+          CIBW_PRERELEASE_PYTHONS: False
+
+      - uses: actions/upload-artifact@v2
+        with:
+          path: wheelhouse/*.whl
+
diff -pruN 0.8.0-0.3/.github/workflows/wheels_osx.yml 0.8.20-1/.github/workflows/wheels_osx.yml
--- 0.8.0-0.3/.github/workflows/wheels_osx.yml	1970-01-01 00:00:00.000000000 +0000
+++ 0.8.20-1/.github/workflows/wheels_osx.yml	2022-02-21 10:55:27.000000000 +0000
@@ -0,0 +1,31 @@
+name: Build wheel on osx
+on: [push]
+env:
+  CIBW_BUILD_VERBOSITY: 1
+  CIBW_TEST_REQUIRES: pytest
+  CIBW_TEST_COMMAND: "pytest --pyargs scrypt"
+jobs:
+  build_osx_wheels:
+    name: Build wheels on macos-latest
+    runs-on: macos-latest
+    steps:
+      - uses: actions/checkout@v2
+
+      # Used to host cibuildwheel
+      - uses: actions/setup-python@v2
+
+      - name: Install cibuildwheel
+        run: python -m pip install cibuildwheel
+
+      - name: Build wheels
+        run: python -m cibuildwheel --output-dir wheelhouse
+        env:
+          # Disable explicitly python 3.11 and building PyPy wheels
+          CFLAGS: "-I/usr/local/opt/openssl@1.1/include"
+          LDFLAGS: "-L/usr/local/opt/openssl@1.1/lib"
+          CIBW_SKIP: cp311-* pp*
+          CIBW_PRERELEASE_PYTHONS: False
+
+      - uses: actions/upload-artifact@v2
+        with:
+          path: wheelhouse/*.whl
diff -pruN 0.8.0-0.3/.github/workflows/wheels_sdist.yml 0.8.20-1/.github/workflows/wheels_sdist.yml
--- 0.8.0-0.3/.github/workflows/wheels_sdist.yml	1970-01-01 00:00:00.000000000 +0000
+++ 0.8.20-1/.github/workflows/wheels_sdist.yml	2022-02-21 10:55:27.000000000 +0000
@@ -0,0 +1,24 @@
+name: Build sdist
+on: [push]
+env:
+  CIBW_BUILD_VERBOSITY: 1
+jobs:
+  make_sdist:
+    name: Make SDist
+    runs-on: ubuntu-latest
+    steps:
+    - uses: actions/checkout@v2
+    - name: Setup Python
+      uses: actions/setup-python@v2
+      with:
+        python-version: '3.8'
+    - name: Install deps
+      run: python -m pip install build twine
+    - name: Build SDist
+      run: python -m build --sdist
+    - uses: actions/upload-artifact@v2
+      with:
+        path: dist/*.tar.gz
+    - name: Check metadata
+      run: twine check dist/*
+      
\ No newline at end of file
diff -pruN 0.8.0-0.3/.github/workflows/wheels_win_32.yml 0.8.20-1/.github/workflows/wheels_win_32.yml
--- 0.8.0-0.3/.github/workflows/wheels_win_32.yml	1970-01-01 00:00:00.000000000 +0000
+++ 0.8.20-1/.github/workflows/wheels_win_32.yml	2022-02-21 10:55:27.000000000 +0000
@@ -0,0 +1,36 @@
+name: Build wheel on win32
+on: [push]
+env:
+  CIBW_BUILD_VERBOSITY: 1
+  CIBW_ARCHS: "auto32"
+  # Run the package tests using `pytest`
+  CIBW_TEST_REQUIRES: pytest
+  CIBW_TEST_COMMAND: "pytest --pyargs scrypt"
+jobs:
+      
+  build_wheels_for_win:
+    name: Build wheels on Win32
+    runs-on: windows-latest
+    steps:
+      - uses: actions/checkout@v2
+
+      # Used to host cibuildwheel
+      - uses: actions/setup-python@v2
+
+      - name: Install cibuildwheel
+        run: python -m pip install cibuildwheel
+
+      - name: install openssl (32 bit)
+        shell: pwsh
+        run: choco install openssl --limitoutput --x86
+
+      - name: Build wheels
+        run: python -m cibuildwheel --output-dir wheelhouse
+        env:
+          # Disable explicitly python 3.10 and building PyPy wheels
+          CIBW_SKIP: cp310-* pp*
+          CIBW_PRERELEASE_PYTHONS: False
+
+      - uses: actions/upload-artifact@v2
+        with:
+          path: wheelhouse/*.whl
diff -pruN 0.8.0-0.3/.github/workflows/wheels_win_64.yml 0.8.20-1/.github/workflows/wheels_win_64.yml
--- 0.8.0-0.3/.github/workflows/wheels_win_64.yml	1970-01-01 00:00:00.000000000 +0000
+++ 0.8.20-1/.github/workflows/wheels_win_64.yml	2022-02-21 10:55:27.000000000 +0000
@@ -0,0 +1,36 @@
+name: Build wheel on win64
+on: [push]
+env:
+  CIBW_BUILD_VERBOSITY: 1
+  CIBW_ARCHS: "auto64"
+  # Run the package tests using `pytest`
+  CIBW_TEST_REQUIRES: pytest
+  CIBW_TEST_COMMAND: "pytest --pyargs scrypt"
+jobs:
+      
+  build_wheels_for_win:
+    name: Build wheels on Win64
+    runs-on: windows-latest
+    steps:
+      - uses: actions/checkout@v2
+
+      # Used to host cibuildwheel
+      - uses: actions/setup-python@v2
+
+      - name: Install cibuildwheel
+        run: python -m pip install cibuildwheel
+
+      - name: install openssl (64 bit)
+        shell: pwsh
+        run: choco install openssl --limitoutput
+
+      - name: Build wheels
+        run: python -m cibuildwheel --output-dir wheelhouse
+        env:
+          # Disable explicitly python 3.10 and building PyPy wheels
+          CIBW_SKIP: cp310-* pp*
+          CIBW_PRERELEASE_PYTHONS: False
+
+      - uses: actions/upload-artifact@v2
+        with:
+          path: wheelhouse/*.whl
diff -pruN 0.8.0-0.3/.gitignore 0.8.20-1/.gitignore
--- 0.8.0-0.3/.gitignore	1970-01-01 00:00:00.000000000 +0000
+++ 0.8.20-1/.gitignore	2022-02-21 10:55:27.000000000 +0000
@@ -0,0 +1,99 @@
+# Byte-compiled / optimized / DLL files
+__pycache__/
+*.py[cod]
+*$py.class
+
+# C extensions
+*.so
+
+# Distribution / packaging
+.Python
+eggs/
+.eggs/
+wheels/
+*.egg-info/
+.installed.cfg
+*.egg
+dist/
+
+# PyInstaller
+#  Usually these files are written by a python script from a template
+#  before PyInstaller builds the exe, so as to inject date/other infos into it.
+*.manifest
+*.spec
+
+# Installer logs
+pip-log.txt
+pip-delete-this-directory.txt
+
+
+# Unit test / coverage reports
+htmlcov/
+.tox/
+.coverage
+.coverage.*
+.cache
+nosetests.xml
+coverage.xml
+*.cover
+.hypothesis/
+
+# Translations
+*.mo
+*.pot
+
+# Django stuff:
+*.log
+local_settings.py
+
+# Flask stuff:
+instance/
+.webassets-cache
+
+# Scrapy stuff:
+.scrapy
+
+# Sphinx documentation
+docs/_build/
+
+# PyBuilder
+target/
+
+# Jupyter Notebook
+.ipynb_checkpoints
+
+# pyenv
+.python-version
+
+# celery beat schedule file
+celerybeat-schedule
+
+# SageMath parsed files
+*.sage.py
+
+# dotenv
+.env
+
+# virtualenv
+.venv
+venv/
+ENV/
+
+# Spyder project settings
+.spyderproject
+.spyproject
+
+# Rope project settings
+.ropeproject
+
+# mkdocs documentation
+/site
+
+/build
+
+# mypy
+.mypy_cache/
+
+# wing
+*.wpr
+*.wpu
\ No newline at end of file
diff -pruN 0.8.0-0.3/LICENSE 0.8.20-1/LICENSE
--- 0.8.0-0.3/LICENSE	1970-01-01 00:00:00.000000000 +0000
+++ 0.8.20-1/LICENSE	2022-02-21 10:55:27.000000000 +0000
@@ -0,0 +1,26 @@
+BSD 2-Clause License
+
+Copyright (c)   2010-2016, Magnus Hallin
+                2018-2021, Holger Nahrstaedt
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice, this
+  list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright notice,
+  this list of conditions and the following disclaimer in the documentation
+  and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff -pruN 0.8.0-0.3/MANIFEST.in 0.8.20-1/MANIFEST.in
--- 0.8.0-0.3/MANIFEST.in	2016-09-17 13:29:41.000000000 +0000
+++ 0.8.20-1/MANIFEST.in	2022-02-21 10:55:27.000000000 +0000
@@ -1,10 +1,28 @@
-recursive-include scrypt-1.2.0 *.h
+recursive-include scrypt-1.2.1 *.h
+recursive-include scrypt-windows-stubs *.h
 include README.rst
+include LICENSE
+include setup.py
+include *.txt
+include tox.ini
 include src/*.c
+include scrypt-windows-stubs/*.c
+include MANIFEST.in
 
-include tests/__init__.py
-include tests/ciphertexts.csv
-include tests/hashvectors.csv
-include tests/test_scrypt.py
-include tests/test_scrypt_py2x.py
-include tests/test_scrypt_py3x.py
+include scrypt/__init__.py
+include scrypt/scrypt.py
+include scrypt/tests/__init__.py
+include scrypt/tests/ciphertexts.csv
+include scrypt/tests/hashvectors.csv
+include scrypt/tests/test_scrypt_c_module.py
+include scrypt/tests/test_scrypt.py
+include scrypt/tests/test_scrypt_py2x.py
+include scrypt/tests/test_scrypt_py3x.py
+
+# Exclude what we don't want to include
+prune build
+prune doc/build
+prune */__pycache__
+
+global-exclude *.py[cod] *.egg *.egg-info
+global-exclude *~ *.bak *.swp
diff -pruN 0.8.0-0.3/PKG-INFO 0.8.20-1/PKG-INFO
--- 0.8.0-0.3/PKG-INFO	2016-09-17 13:30:16.000000000 +0000
+++ 0.8.20-1/PKG-INFO	1970-01-01 00:00:00.000000000 +0000
@@ -1,141 +0,0 @@
-Metadata-Version: 1.1
-Name: scrypt
-Version: 0.8.0
-Summary: Bindings for the scrypt key derivation function library
-Home-page: http://bitbucket.org/mhallin/py-scrypt
-Author: Magnus Hallin
-Author-email: mhallin@gmail.com
-License: 2-clause BSD
-Description: =========================
-         Python scrypt_ bindings
-        =========================
-        
-        This is a set of Python_ bindings for the scrypt_ key derivation
-        function.
-        
-        Scrypt is useful when encrypting password as it is possible to specify
-        a *minimum* amount of time to use when encrypting and decrypting. If,
-        for example, a password takes 0.05 seconds to verify, a user won't
-        notice the slight delay when signing in, but doing a brute force
-        search of several billion passwords will take a considerable amount of
-        time. This is in contrast to more traditional hash functions such as
-        MD5 or the SHA family which can be implemented extremely fast on cheap
-        hardware.
-        
-        Installation
-        ============
-        
-        You can install py-scrypt from this repository if you want the latest
-        but possibly non-compiling version::
-        
-            $ hg clone http://bitbucket.org/mhallin/py-scrypt
-            $ cd py-scrypt
-            $ python setup.py build
-        
-            Become superuser (or use virtualenv):
-            # python setup.py install
-        
-            Run tests after install:
-            $ python setup.py test
-        
-        Or you can install the latest release from PyPi::
-        
-            $ pip install scrypt
-        
-        If you want py-scrypt for your Python 3 environment, just run the
-        above commands with your Python 3 interpreter. Py-scrypt supports both
-        Python 2 and 3.
-        
-        From version 0.6.0 (not available on PyPi yet), py-scrypt supports
-        PyPy as well.
-        
-        Usage
-        =====
-        
-        Fore encryption/decryption, the library exports two functions
-        ``encrypt`` and ``decrypt``::
-        
-            >>> import scrypt
-            >>> data = scrypt.encrypt('a secret message', 'password', maxtime=0.1) # This will take at least 0.1 seconds
-            >>> data[:20]
-            'scrypt\x00\r\x00\x00\x00\x08\x00\x00\x00\x01RX9H'
-            >>> scrypt.decrypt(data, 'password', maxtime=0.1) # This will also take at least 0.1 seconds
-            'a secret message'
-            >>> scrypt.decrypt(data, 'password', maxtime=0.05) # scrypt won't be able to decrypt this data fast enough
-            Traceback (most recent call last):
-              File "<stdin>", line 1, in <module>
-            scrypt.error: decrypting file would take too long
-            >>> scrypt.decrypt(data, 'wrong password', maxtime=0.1) # scrypt will throw an exception if the password is incorrect
-            Traceback (most recent call last):
-              File "<stdin>", line 1, in <module>
-            scrypt.error: password is incorrect
-        
-        From these, one can make a simple password verifier using the following
-        functions::
-        
-            def hash_password(password, maxtime=0.5, datalength=64):
-                return scrypt.encrypt(os.urandom(datalength), password, maxtime=maxtime)
-        
-            def verify_password(hashed_password, guessed_password, maxtime=0.5):
-                try:
-                    scrypt.decrypt(hashed_password, guessed_password, maxtime)
-                    return True
-                except scrypt.error:
-                    return False
-        
-        
-        But, if you want output that is deterministic and constant in size,
-        you can use the ``hash`` function::
-        
-            >>> import scrypt
-            >>> h1 = scrypt.hash('password', 'random salt')
-            >>> len(h1)  # The hash will be 64 bytes by default, but is overridable.
-            64
-            >>> h1[:10]
-            '\xfe\x87\xf3hS\tUo\xcd\xc8'
-            >>> h2 = scrypt.hash('password', 'random salt')
-            >>> h1 == h2 # The hash function is deterministic
-            True
-        
-        
-        Acknowledgements
-        ================
-        
-        Scrypt_ was created by Colin Percival and is licensed as 2-clause BSD.
-        Since scrypt does not normally build as a shared library, I have included
-        the source for the currently latest version of the library in this
-        repository. When a new version arrives, I will update these sources.
-        
-        `Kelvin Wong`_ on Bitbucket provided changes to make the library
-        available on Mac OS X 10.6 and earlier, as well as changes to make the
-        library work more like the command-line version of scrypt by
-        default. Kelvin also contributed with the unit tests, lots of cross
-        platform testing and work on the ``hash`` function.
-        
-        Burstaholic_ on Bitbucket provided the necessary changes to make
-        the library build on Windows.
-        
-        The `python-appveyor-demo`_ repository for setting up automated Windows
-        builds for a multitude of Python versions.
-        
-        License
-        =======
-        
-        This library is licensed under the same license as scrypt; 2-clause BSD.
-        
-        .. _scrypt: http://www.tarsnap.com/scrypt.html
-        .. _Python: http://python.org
-        .. _Burstaholic: https://bitbucket.org/Burstaholic
-        .. _Kelvin Wong: https://bitbucket.org/kelvinwong_ca
-        .. _python-appveyor-demo: https://github.com/ogrisel/python-appveyor-demo
-        
-Platform: UNKNOWN
-Classifier: Development Status :: 4 - Beta
-Classifier: Intended Audience :: Developers
-Classifier: License :: OSI Approved :: BSD License
-Classifier: Programming Language :: Python :: 2.7
-Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.4
-Classifier: Programming Language :: Python :: 3.5
-Classifier: Topic :: Security :: Cryptography
-Classifier: Topic :: Software Development :: Libraries
diff -pruN 0.8.0-0.3/pyproject.toml 0.8.20-1/pyproject.toml
--- 0.8.0-0.3/pyproject.toml	1970-01-01 00:00:00.000000000 +0000
+++ 0.8.20-1/pyproject.toml	2022-02-21 10:55:27.000000000 +0000
@@ -0,0 +1,9 @@
+[tool.cibuildwheel.linux]
+before-all = "yum install -y openssl-devel"
+
+[[tool.cibuildwheel.overrides]]
+select = "*-musllinux*"
+before-all = "apk add openssl-dev"
+
+[tool.cibuildwheel.macos]
+before-all = "brew install openssl@1.1"
\ No newline at end of file
diff -pruN 0.8.0-0.3/README.rst 0.8.20-1/README.rst
--- 0.8.0-0.3/README.rst	2016-09-17 11:45:00.000000000 +0000
+++ 0.8.20-1/README.rst	2022-02-21 10:55:27.000000000 +0000
@@ -5,6 +5,23 @@
 This is a set of Python_ bindings for the scrypt_ key derivation
 function.
 
+.. image:: https://img.shields.io/pypi/v/scrypt.svg
+    :target: https://pypi.python.org/pypi/scrypt/
+    :alt: Latest Version
+  
+.. image:: https://anaconda.org/conda-forge/scrypt/badges/version.svg   
+    :target: https://anaconda.org/conda-forge/scrypt
+  
+.. image:: https://anaconda.org/conda-forge/scrypt/badges/downloads.svg   
+    :target: https://anaconda.org/conda-forge/scrypt
+
+
+.. image:: https://ci.appveyor.com/api/projects/status/h644bjbdawke9vf2?svg=true 
+    :target: https://ci.appveyor.com/project/holger80/py-scrypt
+
+.. image:: https://www.travis-ci.com/holgern/py-scrypt.svg?branch=master
+    :target: https://www.travis-ci.com/holgern/py-scrypt
+
 Scrypt is useful when encrypting password as it is possible to specify
 a *minimum* amount of time to use when encrypting and decrypting. If,
 for example, a password takes 0.05 seconds to verify, a user won't
@@ -17,10 +34,39 @@ hardware.
 Installation
 ============
 
+For Debian and Ubuntu, please ensure that the following packages are installed:
+	
+.. code:: bash
+
+    $ sudo apt-get install build-essential libssl-dev python-dev
+
+For Fedora and RHEL-derivatives, please ensure that the following packages are installed:
+
+.. code:: bash
+
+    $ sudo yum install gcc openssl-devel python-devel
+
+For OSX, please do the following::
+
+    $ brew install openssl
+    $ export CFLAGS="-I$(brew --prefix openssl)/include $CFLAGS"
+    $ export LDFLAGS="-L$(brew --prefix openssl)/lib $LDFLAGS"
+
+For OSX, you can also use the precompiled wheels. They are installed by::
+
+    $ pip install scrypt 
+	
+For Windows, please use the precompiled wheels. They are installed by::
+
+    $ pip install scrypt
+
+For Windows, when the package should be compiled, the development package from https://slproweb.com/products/Win32OpenSSL.html is needed.
+It needs to be installed to C:\OpenSSL-Win64.
+
 You can install py-scrypt from this repository if you want the latest
 but possibly non-compiling version::
 
-    $ hg clone http://bitbucket.org/mhallin/py-scrypt
+    $ git clone https://github.com/holgern/py-scrypt.git
     $ cd py-scrypt
     $ python setup.py build
 
@@ -34,6 +80,13 @@ Or you can install the latest release fr
 
     $ pip install scrypt
 
+Users of the Anaconda_ Python distribution can directly obtain pre-built
+Windows, Intel Linux or macOS / OSX binaries from the conda-forge channel.
+This can be done via::
+
+    $ conda install -c conda-forge scrypt
+
+
 If you want py-scrypt for your Python 3 environment, just run the
 above commands with your Python 3 interpreter. Py-scrypt supports both
 Python 2 and 3.
@@ -41,6 +94,102 @@ Python 2 and 3.
 From version 0.6.0 (not available on PyPi yet), py-scrypt supports
 PyPy as well.
 
+Changelog
+=========
+0.8.20
+------
+* Fix #8 by adding missing gettimeofday.c to MANIFEST.in
+
+0.8.19
+------
+* Use RtlGenRandom instead of CryptGenRandom on windows (Thanks to https://github.com/veorq/cryptocoding/)
+* Add check for c:\Program Files\OpenSSL-Win64 and c:\Program Files\OpenSSL-Win32
+
+0.8.18
+------
+* add wheel for python 3.9
+
+0.8.17
+------
+
+* add_dll_directory for python 3.8 on windows, as importlib.util.find_spec does not search all paths anymore 
+ 
+0.8.16
+------
+
+* Add additional test vector from RFC (thanks to @ChrisMacNaughton)
+
+0.8.15
+------
+
+* Fix missing import
+
+
+0.8.14
+------
+
+* fix imp deprecation warning
+
+
+0.8.13
+------
+
+* improve build for conda forge
+
+0.8.12
+------
+
+* Add SCRYPT_WINDOWS_LINK_LEGACY_OPENSSL environment variable, when set, openssl 1.0.2 is linked
+
+0.8.11
+------
+
+* fix build for conda feedstock
+
+0.8.10
+------
+
+* fix typo
+
+0.8.9
+-----
+
+* use the static libcrypto_static for windows and openssl 1.1.1
+
+0.8.8
+-----
+
+* setup.py for windows improved, works with openssl 1.0.2 and 1.1.1
+
+0.8.7
+-----
+
+* setup.py for windows fixed
+
+0.8.6
+-----
+
+* setup.py fixed, scrypt could not be imported in version 0.8.5
+
+0.8.5
+-----
+
+* MANIFEST.in fixed
+* scrypt.py moved into own scrypt directory with __init__.py 
+* openssl library path for osx wheel repaired
+
+0.8.4
+-----
+
+* __version__ added to scrypt
+* missing void in sha256.c fixed
+
+0.8.3
+-----
+
+* scrypt updated to 1.2.1
+* Wheels are created for python 3.6
+
 Usage
 =====
 
@@ -120,3 +269,4 @@ This library is licensed under the same
 .. _Burstaholic: https://bitbucket.org/Burstaholic
 .. _Kelvin Wong: https://bitbucket.org/kelvinwong_ca
 .. _python-appveyor-demo: https://github.com/ogrisel/python-appveyor-demo
+.. _Anaconda: https://www.continuum.io
diff -pruN 0.8.0-0.3/scrypt/__init__.py 0.8.20-1/scrypt/__init__.py
--- 0.8.0-0.3/scrypt/__init__.py	1970-01-01 00:00:00.000000000 +0000
+++ 0.8.20-1/scrypt/__init__.py	2022-02-21 10:55:27.000000000 +0000
@@ -0,0 +1 @@
+from .scrypt import *
diff -pruN 0.8.0-0.3/scrypt/scrypt.py 0.8.20-1/scrypt/scrypt.py
--- 0.8.0-0.3/scrypt/scrypt.py	1970-01-01 00:00:00.000000000 +0000
+++ 0.8.20-1/scrypt/scrypt.py	2022-02-21 10:55:27.000000000 +0000
@@ -0,0 +1,241 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+import os
+import sys
+from ctypes import (cdll,
+                    POINTER, pointer,
+                    c_char_p,
+                    c_size_t, c_double, c_int, c_uint64, c_uint32,
+                    create_string_buffer)
+IS_PY2 = sys.version_info < (3, 0, 0, 'final', 0)
+if IS_PY2:
+    import imp
+    _scrypt = cdll.LoadLibrary(imp.find_module('_scrypt')[1])
+else:
+    if sys.version_info >= (3, 8) and sys.platform == 'win32':
+        lib_path = os.path.join(os.path.normpath(sys.prefix), 'Library', 'bin')
+        build_dir = os.path.join(os.path.dirname(__file__), '../')
+        if os.path.exists(lib_path):
+            os.add_dll_directory(lib_path)
+        if os.path.exists(build_dir):
+            os.add_dll_directory(build_dir)
+    import importlib
+    import importlib.util
+    _scrypt = cdll.LoadLibrary(importlib.util.find_spec('_scrypt').origin)
+
+__version__ = '0.8.18'
+
+_scryptenc_buf = _scrypt.exp_scryptenc_buf
+_scryptenc_buf.argtypes = [c_char_p,  # const uint_t  *inbuf
+                           c_size_t,  # size_t         inbuflen
+                           c_char_p,  # uint8_t       *outbuf
+                           c_char_p,  # const uint8_t *passwd
+                           c_size_t,  # size_t         passwdlen
+                           c_size_t,  # size_t         maxmem
+                           c_double,  # double         maxmemfrac
+                           c_double,  # double         maxtime
+                           c_int,     # int            verbose
+                           ]
+_scryptenc_buf.restype = c_int
+
+_scryptdec_buf = _scrypt.exp_scryptdec_buf
+_scryptdec_buf.argtypes = [c_char_p,           # const uint8_t *inbuf
+                           c_size_t,           # size_t         inbuflen
+                           c_char_p,           # uint8_t       *outbuf
+                           POINTER(c_size_t),  # size_t        *outlen
+                           c_char_p,           # const uint8_t *passwd
+                           c_size_t,           # size_t         passwdlen
+                           c_size_t,           # size_t         maxmem
+                           c_double,           # double         maxmemfrac
+                           c_double,           # double         maxtime
+                           c_int,              # int            verbose
+                           c_int,              # int            force
+                           ]
+_scryptdec_buf.restype = c_int
+
+_crypto_scrypt = _scrypt.exp_crypto_scrypt
+_crypto_scrypt.argtypes = [c_char_p,  # const uint8_t *passwd
+                           c_size_t,  # size_t         passwdlen
+                           c_char_p,  # const uint8_t *salt
+                           c_size_t,  # size_t         saltlen
+                           c_uint64,  # uint64_t       N
+                           c_uint32,  # uint32_t       r
+                           c_uint32,  # uint32_t       p
+                           c_char_p,  # uint8_t       *buf
+                           c_size_t,  # size_t         buflen
+                           ]
+_crypto_scrypt.restype = c_int
+
+ERROR_MESSAGES = ['success',
+                  'getrlimit or sysctl(hw.usermem) failed',
+                  'clock_getres or clock_gettime failed',
+                  'error computing derived key',
+                  'could not read salt from /dev/urandom',
+                  'error in OpenSSL',
+                  'malloc failed',
+                  'data is not a valid scrypt-encrypted block',
+                  'unrecognized scrypt format',
+                  'decrypting file would take too much memory',
+                  'decrypting file would take too long',
+                  'password is incorrect',
+                  'error writing output file',
+                  'error reading input file']
+
+MAXMEM_DEFAULT = 0
+MAXMEMFRAC_DEFAULT = 0.5
+MAXTIME_DEFAULT = 300.0
+MAXTIME_DEFAULT_ENC = 5.0
+
+
+class error(Exception):
+    def __init__(self, scrypt_code):
+        if isinstance(scrypt_code, int):
+            self._scrypt_code = scrypt_code
+            super(error, self).__init__(ERROR_MESSAGES[scrypt_code])
+        else:
+            self._scrypt_code = -1
+            super(error, self).__init__(scrypt_code)
+
+
+def _ensure_bytes(data):
+    if IS_PY2 and isinstance(data, unicode):
+        raise TypeError('can not encrypt/decrypt unicode objects')
+
+    if not IS_PY2 and isinstance(data, str):
+        return bytes(data, 'utf-8')
+
+    return data
+
+
+def encrypt(input, password,
+            maxtime=MAXTIME_DEFAULT_ENC,
+            maxmem=MAXMEM_DEFAULT,
+            maxmemfrac=MAXMEMFRAC_DEFAULT):
+    """
+    Encrypt a string using a password. The resulting data will have len =
+    len(input) + 128.
+
+    Notes for Python 2:
+      - `input` and `password` must be str instances
+      - The result will be a str instance
+
+    Notes for Python 3:
+      - `input` and `password` can be both str and bytes. If they are str
+        instances, they will be encoded with utf-8
+      - The result will be a bytes instance
+
+    Exceptions raised:
+      - TypeError on invalid input
+      - scrypt.error if encryption failed
+
+    For more information on the `maxtime`, `maxmem`, and `maxmemfrac`
+    parameters, see the scrypt documentation.
+    """
+
+    input = _ensure_bytes(input)
+    password = _ensure_bytes(password)
+
+    outbuf = create_string_buffer(len(input) + 128)
+    # verbose is set to zero
+    result = _scryptenc_buf(input, len(input),
+                            outbuf,
+                            password, len(password),
+                            maxmem, maxmemfrac, maxtime, 0)
+    if result:
+        raise error(result)
+
+    return outbuf.raw
+
+
+def decrypt(input, password,
+            maxtime=MAXTIME_DEFAULT,
+            maxmem=MAXMEM_DEFAULT,
+            maxmemfrac=MAXMEMFRAC_DEFAULT,
+            encoding='utf-8'):
+    """
+    Decrypt a string using a password.
+
+    Notes for Python 2:
+      - `input` and `password` must be str instances
+      - The result will be a str instance
+      - The encoding parameter is ignored
+
+    Notes for Python 3:
+      - `input` and `password` can be both str and bytes. If they are str
+        instances, they wil be encoded with utf-8. `input` *should*
+        really be a bytes instance, since that's what `encrypt` returns.
+      - The result will be a str instance encoded with `encoding`.
+        If encoding=None, the result will be a bytes instance.
+
+    Exceptions raised:
+      - TypeError on invalid input
+      - scrypt.error if decryption failed
+
+    For more information on the `maxtime`, `maxmem`, and `maxmemfrac`
+    parameters, see the scrypt documentation.
+    """
+
+    outbuf = create_string_buffer(len(input))
+    outbuflen = pointer(c_size_t(0))
+
+    input = _ensure_bytes(input)
+    password = _ensure_bytes(password)
+    # verbose and force are set to zero
+    result = _scryptdec_buf(input, len(input),
+                            outbuf, outbuflen,
+                            password, len(password),
+                            maxmem, maxmemfrac, maxtime, 0, 0)
+
+    if result:
+        raise error(result)
+
+    out_bytes = outbuf.raw[:outbuflen.contents.value]
+
+    if IS_PY2 or encoding is None:
+        return out_bytes
+
+    return str(out_bytes, encoding)
+
+
+def hash(password, salt, N=1 << 14, r=8, p=1, buflen=64):
+    """
+    Compute scrypt(password, salt, N, r, p, buflen).
+
+    The parameters r, p, and buflen must satisfy r * p < 2^30 and
+    buflen <= (2^32 - 1) * 32. The parameter N must be a power of 2
+    greater than 1. N, r and p must all be positive.
+
+    Notes for Python 2:
+      - `password` and `salt` must be str instances
+      - The result will be a str instance
+
+    Notes for Python 3:
+      - `password` and `salt` can be both str and bytes. If they are str
+        instances, they wil be encoded with utf-8.
+      - The result will be a bytes instance
+
+    Exceptions raised:
+      - TypeError on invalid input
+      - scrypt.error if scrypt failed
+    """
+
+    outbuf = create_string_buffer(buflen)
+
+    password = _ensure_bytes(password)
+    salt = _ensure_bytes(salt)
+
+    if r * p >= (1 << 30) or N <= 1 or (N & (N - 1)) != 0 or p < 1 or r < 1:
+        raise error('hash parameters are wrong (r*p should be < 2**30, and N should be a power of two > 1)')
+
+    result = _crypto_scrypt(password, len(password),
+                            salt, len(salt),
+                            N, r, p,
+                            outbuf, buflen, 0)
+
+    if result:
+        raise error('could not compute hash')
+
+    return outbuf.raw
+
+
+__all__ = ['error', 'encrypt', 'decrypt', 'hash']
diff -pruN 0.8.0-0.3/scrypt/tests/ciphertexts.csv 0.8.20-1/scrypt/tests/ciphertexts.csv
--- 0.8.0-0.3/scrypt/tests/ciphertexts.csv	1970-01-01 00:00:00.000000000 +0000
+++ 0.8.20-1/scrypt/tests/ciphertexts.csv	2022-02-21 10:55:27.000000000 +0000
@@ -0,0 +1,6 @@
+input,password,maxtime,maxmem,maxmemfrac,ciphertext
+message,password,0.01,0,0.0625,736372797074000a00000008000000019f6d3fe5e9423a12d330e35089befdfbb476c7d4faea91492a2561f942c1599701aba424220218b9f81812df06d7cf2a281fd0fdbc7c9d978c335bf5209b1062ee2e49993c4d3a37d347ad6bf0eaecc2fe579a6f320b0acf475882c222c0ba34a7ac5379bedc82358bb3f736ea31d4b824e8bc95c75579
+message,password,5.0000,0.0000,0.1250,736372797074000a00000008000000cb974d55992fea307caa3593205c8851cd56b3ddfd241ee7b1c075cfd2e2f871dddcee71b6bc2b6b075caa1699ea58ce32e9fcd802b18069828201692380574e23e84c2d39d6a951c9c2401dea1a0fa44195b01fca9332f7aac223c84251c69a28037788e09cf297a003a62e2e7c5b6f039e3c1d21fa5da6
+message,password,0.5000,0.0000,0.0625,736372797074000a00000008000000141429bb22aef840e1dde29564dada8f2a77fc2855fe8c9e27e5bf5df4a0eec330344e8471bf83e2466a28acc9d1813a3e50e64697fb8e9c7c17954950f16a5b78fe114d8b147c5936802fe52b17f83e6da9de884257f2a938aa37c2e92b1c33cd9afd0f5e91baba29be4b1c0709bd2a31a4c52394f9b0d4
+message,password,0.5000,0.0000,0.1250,736372797074000a0000000800000014e9baa49b57b2e5b561df54121d870532714f063f295c15ca48e32b677e8e11126ab8da24683951749a19eede36ea3768cb01e8eda6c0f570db7051e07e99d2d687ce28f96aa2e6afa8a0a8c5d902c847e041e14435a22d873c4e676f7a7f5ab9107171b583d02724c056707640931a3c160b9e0ef87bae
+message,password,0.5000,10485760.0000,0.1250,736372797074000a0000000800000014e53c55cd89b6e2de639c1621d92e79212e5f4fc793387435486427eb8adeb192382b5b6397f98ac66fa528a13cba01bd611082369fe1e2244a01ba8329ff6fcaa2db5e87fb75683ae6fc636d873c2e004a0209b947c7b8e805174d65ec0ac2cb597baadae6cf092c33a5096590860b51570faa89e39bf0
\ No newline at end of file
diff -pruN 0.8.0-0.3/scrypt/tests/hashvectors.csv 0.8.20-1/scrypt/tests/hashvectors.csv
--- 0.8.0-0.3/scrypt/tests/hashvectors.csv	1970-01-01 00:00:00.000000000 +0000
+++ 0.8.20-1/scrypt/tests/hashvectors.csv	2022-02-21 10:55:27.000000000 +0000
@@ -0,0 +1,6 @@
+password,salt,n,r,p,hexhash
+,,16,1,1,77d6576238657b203b19ca42c18a0497f16b4844e3074ae8dfdffa3fede21442fcd0069ded0948f8326a753a0fc81f17e8d3e0fb2e0d3628cf35e20c38d18906
+password,NaCl,1024,8,16,fdbabe1c9d3472007856e7190d01e9fe7c6ad7cbc8237830e77376634b3731622eaf30d92e22a3886ff109279d9830dac727afb94a83ee6d8360cbdfa2cc0640
+pleaseletmein,SodiumChloride,16384,8,1,7023bdcb3afd7348461c06cd81fd38ebfda8fbba904f8e3ea9b543f6545da1f2d5432955613f0fcf62d49705242a9af9e61e85dc0d651e40dfcf017b45575887
+pleaseletmein,SodiumChloride,32768,16,4,cbc397a9b5f5a53048c5b9f039ee1246d9532c8089fb346a4ab47cd0701febf18652b1ee042e070d1b6c631c43fd05ececd5b165ee1c2ffc1a2e98406fc2cd52
+pleaseletmein,SodiumChloride,1048576,8,1,2101cb9b6a511aaeaddbbe09cf70f881ec568d574a2ffd4dabe5ee9820adaa478e56fd8f4ba5d09ffa1c6d927c40f4c337304049e8a952fbcbf45c6fa77a41a4
\ No newline at end of file
diff -pruN 0.8.0-0.3/scrypt/tests/test_scrypt_c_module.py 0.8.20-1/scrypt/tests/test_scrypt_c_module.py
--- 0.8.0-0.3/scrypt/tests/test_scrypt_c_module.py	1970-01-01 00:00:00.000000000 +0000
+++ 0.8.20-1/scrypt/tests/test_scrypt_c_module.py	2022-02-21 10:55:27.000000000 +0000
@@ -0,0 +1,11 @@
+from sys import version_info, exit
+import unittest as testm
+
+
+class TestScryptCModule(testm.TestCase):
+    def test_import_module(self):
+        """Test importing the _scrypt module"""
+
+        import _scrypt
+
+        self.assertTrue(_scrypt)
diff -pruN 0.8.0-0.3/scrypt/tests/test_scrypt.py 0.8.20-1/scrypt/tests/test_scrypt.py
--- 0.8.0-0.3/scrypt/tests/test_scrypt.py	1970-01-01 00:00:00.000000000 +0000
+++ 0.8.20-1/scrypt/tests/test_scrypt.py	2022-02-21 10:55:27.000000000 +0000
@@ -0,0 +1,274 @@
+# -*- coding: utf-8 -*-
+
+from os import urandom
+from os.path import dirname, abspath, sep
+from sys import version_info, exit
+from csv import reader
+from binascii import a2b_hex, b2a_hex
+import scrypt
+import unittest as testm
+
+
+class TestScrypt(testm.TestCase):
+
+    def setUp(self):
+        self.input = "message"
+        self.password = "password"
+        self.longinput = str(urandom(100000))
+        self.five_minutes = 300.0
+        self.five_seconds = 5.0
+        self.one_byte = 1  # in Bytes
+        self.one_megabyte = 1024 * 1024  # in Bytes
+        self.ten_megabytes = 10 * self.one_megabyte
+        base_dir = dirname(abspath(__file__)) + sep
+        cvf = open(base_dir + "ciphertexts.csv", "r")
+        ciphertxt_reader = reader(cvf, dialect="excel")
+        self.ciphertexts = []
+        for row in ciphertxt_reader:
+            self.ciphertexts.append(row)
+        cvf.close()
+        self.ciphertext = a2b_hex(bytes(self.ciphertexts[1][5].encode('ascii')))
+
+    def test_encrypt_decrypt(self):
+        """Test encrypt for simple encryption and decryption"""
+        s = scrypt.encrypt(self.input, self.password, 0.1)
+        m = scrypt.decrypt(s, self.password)
+        self.assertEqual(m, self.input)
+
+    def test_encrypt(self):
+        """Test encrypt takes input and password strings as
+        positional arguments and produces ciphertext"""
+        s = scrypt.encrypt(self.input, self.password)
+        self.assertEqual(len(s), 128 + len(self.input))
+
+    def test_encrypt_input_and_password_as_keywords(self):
+        """Test encrypt for input and password accepted as keywords"""
+        s = scrypt.encrypt(password=self.password, input=self.input)
+        m = scrypt.decrypt(s, self.password)
+        self.assertEqual(m, self.input)
+
+    def test_encrypt_missing_input_keyword_argument(self):
+        """Test encrypt raises TypeError if keyword argument missing input"""
+        self.assertRaises(TypeError, lambda: scrypt.encrypt(password=self.password))
+
+    def test_encrypt_missing_password_positional_argument(self):
+        """Test encrypt raises TypeError if second positional argument missing
+        (password)"""
+        self.assertRaises(TypeError, lambda: scrypt.encrypt(self.input))
+
+    def test_encrypt_missing_both_required_positional_arguments(self):
+        """Test encrypt raises TypeError if both positional arguments missing
+        (input and password)"""
+        self.assertRaises(TypeError, lambda: scrypt.encrypt())
+
+    def test_encrypt_maxtime_positional(self):
+        """Test encrypt maxtime accepts maxtime at position 3"""
+        s = scrypt.encrypt(self.input, self.password, 0.01)
+        m = scrypt.decrypt(s, self.password)
+        self.assertEqual(m, self.input)
+
+    def test_encrypt_maxtime_key(self):
+        """Test encrypt maxtime accepts maxtime as keyword argument"""
+        s = scrypt.encrypt(self.input, self.password, maxtime=0.01)
+        m = scrypt.decrypt(s, self.password)
+        self.assertEqual(m, self.input)
+
+    def test_encrypt_maxmem_positional(self):
+        """Test encrypt maxmem accepts 4th positional argument and exactly
+        (1 megabyte) of storage to use for V array"""
+        s = scrypt.encrypt(self.input, self.password, 0.01, self.one_megabyte)
+        m = scrypt.decrypt(s, self.password)
+        self.assertEqual(m, self.input)
+
+    def test_encrypt_maxmem_undersized(self):
+        """Test encrypt maxmem accepts (< 1 megabyte) of storage to use for V array"""
+        s = scrypt.encrypt(self.input, self.password, 0.01, self.one_byte)
+        m = scrypt.decrypt(s, self.password)
+        self.assertEqual(m, self.input)
+
+    def test_encrypt_maxmem_in_normal_range(self):
+        """Test encrypt maxmem accepts (> 1 megabyte) of storage to use for V array"""
+        s = scrypt.encrypt(self.input,
+                           self.password,
+                           0.01,
+                           self.ten_megabytes)
+        m = scrypt.decrypt(s, self.password)
+        self.assertEqual(m, self.input)
+
+    def test_encrypt_maxmem_keyword_argument(self):
+        """Test encrypt maxmem accepts exactly (1 megabyte) of storage to use for
+        V array"""
+        s = scrypt.encrypt(self.input,
+                           self.password,
+                           maxmem=self.one_megabyte,
+                           maxtime=0.01)
+        m = scrypt.decrypt(s, self.password)
+        self.assertEqual(m, self.input)
+
+    def test_encrypt_maxmemfrac_positional(self):
+        """Test encrypt maxmemfrac accepts 5th positional argument of 1/16 total
+        memory for V array"""
+        s = scrypt.encrypt(self.input, self.password, 0.01, 0, 0.0625)
+        m = scrypt.decrypt(s, self.password)
+        self.assertEqual(m, self.input)
+
+    def test_encrypt_maxmemfrac_keyword_argument(self):
+        """Test encrypt maxmemfrac accepts keyword argument of 1/16 total memory for
+        V array"""
+        s = scrypt.encrypt(self.input, self.password, maxmemfrac=0.0625,
+                           maxtime=0.01)
+        m = scrypt.decrypt(s, self.password)
+        self.assertEqual(m, self.input)
+
+    def test_encrypt_long_input(self):
+        """Test encrypt accepts long input for encryption"""
+        s = scrypt.encrypt(self.longinput, self.password, 0.1)
+        self.assertEqual(len(s), 128 + len(self.longinput))
+
+    def test_encrypt_raises_error_on_invalid_keyword(self):
+        """Test encrypt raises TypeError if invalid keyword used in argument"""
+        self.assertRaises(TypeError, lambda: scrypt.encrypt(self.input,
+            self.password, nonsense="Raise error"))
+
+    def test_decrypt_from_csv_ciphertexts(self):
+        """Test decrypt function with precalculated combinations"""
+        for row in self.ciphertexts[1:]:
+            h = scrypt.decrypt(a2b_hex(bytes(row[5].encode('ascii'))), row[1])
+            self.assertEqual(bytes(h.encode("ascii")), row[0].encode("ascii"))
+
+    def test_decrypt_maxtime_positional(self):
+        """Test decrypt function accepts third positional argument"""
+        m = scrypt.decrypt(self.ciphertext, self.password, self.five_seconds)
+        self.assertEqual(m, self.input)
+
+    def test_decrypt_maxtime_keyword_argument(self):
+        """Test decrypt function accepts maxtime keyword argument"""
+        m = scrypt.decrypt(maxtime=1.0, input=self.ciphertext, password=self.password)
+        self.assertEqual(m, self.input)
+
+    def test_decrypt_maxmem_positional(self):
+        """Test decrypt function accepts fourth positional argument"""
+        m = scrypt.decrypt(self.ciphertext, self.password, self.five_minutes, self.ten_megabytes)
+        self.assertEqual(m, self.input)
+
+    def test_decrypt_maxmem_keyword_argument(self):
+        """Test decrypt function accepts maxmem keyword argument"""
+        m = scrypt.decrypt(maxmem=self.ten_megabytes, input=self.ciphertext, password=self.password)
+        self.assertEqual(m, self.input)
+
+    def test_decrypt_maxmemfrac_positional(self):
+        """Test decrypt function accepts maxmem keyword argument"""
+        m = scrypt.decrypt(self.ciphertext, self.password, self.five_minutes, self.one_megabyte, 0.0625)
+        self.assertEqual(m, self.input)
+
+    def test_decrypt_maxmemfrac_keyword_argument(self):
+        """Test decrypt function accepts maxmem keyword argument"""
+        m = scrypt.decrypt(maxmemfrac=0.625, input=self.ciphertext, password=self.password)
+        self.assertEqual(m, self.input)
+
+    def test_decrypt_raises_error_on_too_little_time(self):
+        """Test decrypt function raises scrypt.error raised if insufficient time allowed for
+        ciphertext decryption"""
+        s = scrypt.encrypt(self.input, self.password, 0.1)
+        self.assertRaises(scrypt.error,
+                          lambda: scrypt.decrypt(s, self.password, .01))
+
+
+class TestScryptHash(testm.TestCase):
+
+    def setUp(self):
+        self.input = "message"
+        self.password = "password"
+        self.salt = "NaCl"
+        self.hashes = []
+        base_dir = dirname(abspath(__file__)) + sep
+        hvf = open(base_dir + "hashvectors.csv", "r")
+        hash_reader = reader(hvf, dialect="excel")
+        for row in hash_reader:
+            self.hashes.append(row)
+        hvf.close()
+
+    def test_hash_vectors_from_csv(self):
+        """Test hash function with precalculated combinations"""
+        for row in self.hashes[1:]:
+            h = scrypt.hash(row[0], row[1], int(row[2]), int(row[3]), int(row[4]))
+            hhex = b2a_hex(h)
+            self.assertEqual(hhex, bytes(row[5].encode("utf-8")))
+
+    def test_hash_buflen_keyword(self):
+        """Test hash takes keyword valid buflen"""
+        h64 = scrypt.hash(self.input, self.salt, buflen=64)
+        h128 = scrypt.hash(self.input, self.salt, buflen=128)
+        self.assertEqual(len(h64), 64)
+        self.assertEqual(len(h128), 128)
+
+    def test_hash_n_positional(self):
+        """Test hash accepts valid N in position 3"""
+        h = scrypt.hash(self.input, self.salt, 256)
+        self.assertEqual(len(h), 64)
+
+    def test_hash_n_keyword(self):
+        """Test hash takes keyword valid N"""
+        h = scrypt.hash(N=256, password=self.input, salt=self.salt)
+        self.assertEqual(len(h), 64)
+
+    def test_hash_r_positional(self):
+        """Test hash accepts valid r in position 4"""
+        h = scrypt.hash(self.input, self.salt, 256, 16)
+        self.assertEqual(len(h), 64)
+
+    def test_hash_r_keyword(self):
+        """Test hash takes keyword valid r"""
+        h = scrypt.hash(r=16, password=self.input, salt=self.salt)
+        self.assertEqual(len(h), 64)
+
+    def test_hash_p_positional(self):
+        """Test hash accepts valid p in position 5"""
+        h = scrypt.hash(self.input, self.salt, 256, 8, 2)
+        self.assertEqual(len(h), 64)
+
+    def test_hash_p_keyword(self):
+        """Test hash takes keyword valid p"""
+        h = scrypt.hash(p=4, password=self.input, salt=self.salt)
+        self.assertEqual(len(h), 64)
+
+    def test_hash_raises_error_on_p_equals_zero(self):
+        """Test hash raises scrypt error on illegal parameter value (p = 0)"""
+        self.assertRaises(scrypt.error,
+                          lambda: scrypt.hash(self.input, self.salt, p=0))
+
+    def test_hash_raises_error_on_negative_p(self):
+        """Test hash raises scrypt error on illegal parameter value (p < 0)"""
+        self.assertRaises(scrypt.error,
+                          lambda: scrypt.hash(self.input, self.salt, p=-1))
+
+    def test_hash_raises_error_on_r_equals_zero(self):
+        """Test hash raises scrypt error on illegal parameter value (r = 0)"""
+        self.assertRaises(scrypt.error,
+                          lambda: scrypt.hash(self.input, self.salt, r=0))
+
+    def test_hash_raises_error_on_negative_r(self):
+        """Test hash raises scrypt error on illegal parameter value (r < 1)"""
+        self.assertRaises(scrypt.error,
+                          lambda: scrypt.hash(self.input, self.salt, r=-1))
+
+    def test_hash_raises_error_r_p_over_limit(self):
+        """Test hash raises scrypt error when parameters r multiplied by p over limit 2**30"""
+        self.assertRaises(scrypt.error,
+                          lambda: scrypt.hash(self.input, self.salt, r=2, p=2 ** 29))
+
+    def test_hash_raises_error_n_not_power_of_two(self):
+        """Test hash raises scrypt error when parameter N is not a power of two {2, 4, 8, 16, etc}"""
+        self.assertRaises(scrypt.error,
+                          lambda: scrypt.hash(self.input, self.salt, N=3))
+
+    def test_hash_raises_error_n_under_limit(self):
+        """Test hash raises scrypt error when parameter N under limit of 1"""
+        self.assertRaises(scrypt.error,
+                          lambda: scrypt.hash(self.input, self.salt, N=1))
+        self.assertRaises(scrypt.error,
+                          lambda: scrypt.hash(self.input, self.salt, N=-1))
+
+
+if __name__ == "__main__":
+    testm.main()
diff -pruN 0.8.0-0.3/scrypt/tests/test_scrypt_py2x.py 0.8.20-1/scrypt/tests/test_scrypt_py2x.py
--- 0.8.0-0.3/scrypt/tests/test_scrypt_py2x.py	1970-01-01 00:00:00.000000000 +0000
+++ 0.8.20-1/scrypt/tests/test_scrypt_py2x.py	2022-02-21 10:55:27.000000000 +0000
@@ -0,0 +1,42 @@
+# -*- coding: utf-8 -*-
+
+from sys import version_info, exit
+import scrypt
+import unittest as testm
+
+
+@testm.skipIf(version_info > (3, 0, 0, 'final', 0), "Tests for Python 2 only")
+class TestScryptForPython2(testm.TestCase):
+
+    def setUp(self):
+        self.input = "message"
+        self.password = "password"
+        self.unicode_text = '\xe1\x93\x84\xe1\x93\x87\xe1\x95\x97\xe1\x92\xbb\xe1\x92\xa5\xe1\x90\x85\xe1\x91\xa6'.decode('utf-8')
+
+    def test_py2_encrypt_fails_on_unicode_input(self):
+        """Test Py2 encrypt raises TypeError when Unicode input passed"""
+        self.assertRaises(TypeError, lambda: scrypt.encrypt(self.unicode_text, self.password))
+
+    def test_py2_encrypt_fails_on_unicode_password(self):
+        """Test Py2 encrypt raises TypeError when Unicode password passed"""
+        self.assertRaises(TypeError, lambda: scrypt.encrypt(self.input, self.unicode_text))
+
+    def test_py2_encrypt_returns_string(self):
+        """Test Py2 encrypt returns str"""
+        e = scrypt.encrypt(self.input, self.password, 0.1)
+        self.assertTrue(isinstance(e, str))
+
+    def test_py2_decrypt_returns_string(self):
+        """Test Py2 decrypt returns str"""
+        s = scrypt.encrypt(self.input, self.password, 0.1)
+        m = scrypt.decrypt(s, self.password)
+        self.assertTrue(isinstance(m, str))
+
+    def test_py2_hash_returns_string(self):
+        """Test Py2 hash return str"""
+        h = scrypt.hash(self.input, self.password)
+        self.assertTrue(isinstance(h, str))
+
+
+if __name__ == "__main__":
+    testm.main()
diff -pruN 0.8.0-0.3/scrypt/tests/test_scrypt_py3x.py 0.8.20-1/scrypt/tests/test_scrypt_py3x.py
--- 0.8.0-0.3/scrypt/tests/test_scrypt_py3x.py	1970-01-01 00:00:00.000000000 +0000
+++ 0.8.20-1/scrypt/tests/test_scrypt_py3x.py	2022-02-21 10:55:27.000000000 +0000
@@ -0,0 +1,47 @@
+# -*- coding: utf-8 -*-
+
+from sys import version_info, exit
+import scrypt
+import unittest as testm
+
+
+@testm.skipIf(version_info < (3, 0, 0, 'final', 0), "Tests for Python 3 only")
+class TestScryptForPy3(testm.TestCase):
+
+    def setUp(self):
+        self.input = "message"
+        self.password = "password"
+        self.byte_text = b'\xe1\x93\x84\xe1\x93\x87\xe1\x95\x97\xe1\x92\xbb\xe1\x92\xa5\xe1\x90\x85\xe1\x91\xa6'
+        self.unicode_text = self.byte_text.decode('utf-8', "strict")
+
+    def test_py3_encrypt_allows_bytes_input(self):
+        """Test Py3 encrypt allows unicode input"""
+        s = scrypt.encrypt(self.byte_text, self.password, 0.1)
+        m = scrypt.decrypt(s, self.password)
+        self.assertEqual(bytes(m.encode("utf-8")), self.byte_text)
+
+    def test_py3_encrypt_allows_bytes_password(self):
+        """Test Py3 encrypt allows unicode password"""
+        s = scrypt.encrypt(self.input, self.byte_text, 0.1)
+        m = scrypt.decrypt(s, self.byte_text)
+        self.assertEqual(m, self.input)
+
+    def test_py3_encrypt_returns_bytes(self):
+        """Test Py3 encrypt return bytes"""
+        s = scrypt.encrypt(self.input, self.password, 0.1)
+        self.assertTrue(isinstance(s, bytes))
+
+    def test_py3_decrypt_returns_unicode_string(self):
+        """Test Py3 decrypt returns Unicode UTF-8 string"""
+        s = scrypt.encrypt(self.input, self.password, 0.1)
+        m = scrypt.decrypt(s, self.password)
+        self.assertTrue(isinstance(m, str))
+
+    def test_py3_hash_returns_bytes(self):
+        """Test Py3 hash return bytes"""
+        h = scrypt.hash(self.input, self.password)
+        self.assertTrue(isinstance(h, bytes))
+
+
+if __name__ == "__main__":
+    testm.main()
diff -pruN 0.8.0-0.3/scrypt-1.2.0/config.h 0.8.20-1/scrypt-1.2.0/config.h
--- 0.8.0-0.3/scrypt-1.2.0/config.h	2016-09-17 12:18:49.000000000 +0000
+++ 0.8.20-1/scrypt-1.2.0/config.h	1970-01-01 00:00:00.000000000 +0000
@@ -1,99 +0,0 @@
-/* config.h.  Generated from config.h.in by configure.  */
-/* config.h.in.  Generated from configure.ac by autoheader.  */
-
-/* Define to 1 if you have the `clock_gettime' function. */
-/* #undef HAVE_CLOCK_GETTIME */
-
-/* Define to 1 if you have the declaration of `be64enc', and to 0 if you
-   don't. */
-#define HAVE_DECL_BE64ENC 0
-
-/* Define to 1 if you have the <err.h> header file. */
-#define HAVE_ERR_H 1
-
-/* Define to 1 if you have the <inttypes.h> header file. */
-#define HAVE_INTTYPES_H 1
-
-/* Define to 1 if you have the `rt' library (-lrt). */
-/* #undef HAVE_LIBRT */
-
-/* Define to 1 if you have the <memory.h> header file. */
-#define HAVE_MEMORY_H 1
-
-/* Define to 1 if you have the `posix_memalign' function. */
-/* #undef HAVE_POSIX_MEMALIGN */
-
-/* Define to 1 if you have the <stdint.h> header file. */
-#define HAVE_STDINT_H 1
-
-/* Define to 1 if you have the <stdlib.h> header file. */
-#define HAVE_STDLIB_H 1
-
-/* Define to 1 if you have the <strings.h> header file. */
-#define HAVE_STRINGS_H 1
-
-/* Define to 1 if you have the <string.h> header file. */
-#define HAVE_STRING_H 1
-
-/* Define to 1 if the system has the type `struct sysinfo'. */
-/* #undef HAVE_STRUCT_SYSINFO */
-
-/* Define to 1 if `mem_unit' is member of `struct sysinfo'. */
-/* #undef HAVE_STRUCT_SYSINFO_MEM_UNIT */
-
-/* Define to 1 if `totalram' is member of `struct sysinfo'. */
-/* #undef HAVE_STRUCT_SYSINFO_TOTALRAM */
-
-/* Define to 1 if the OS has a hw.usermem sysctl */
-/* #undef HAVE_SYSCTL_HW_USERMEM */
-
-/* Define to 1 if you have the `sysinfo' function. */
-/* #undef HAVE_SYSINFO */
-
-/* Define to 1 if you have the <sys/endian.h> header file. */
-/* #undef HAVE_SYS_ENDIAN_H */
-
-/* Define to 1 if you have the <sys/param.h> header file. */
-/* #define HAVE_SYS_PARAM_H */
-
-/* Define to 1 if you have the <sys/stat.h> header file. */
-#define HAVE_SYS_STAT_H 1
-
-/* Define to 1 if you have the <sys/sysinfo.h> header file. */
-/* #undef HAVE_SYS_SYSINFO_H */
-
-/* Define to 1 if you have the <sys/types.h> header file. */
-#define HAVE_SYS_TYPES_H 1
-
-/* Define to 1 if you have the <unistd.h> header file. */
-#define HAVE_UNISTD_H 1
-
-/* Name of package */
-#define PACKAGE "scrypt"
-
-/* Define to the address where bug reports for this package should be sent. */
-#define PACKAGE_BUGREPORT ""
-
-/* Define to the full name of this package. */
-#define PACKAGE_NAME "scrypt"
-
-/* Define to the full name and version of this package. */
-#define PACKAGE_STRING "scrypt 1.2.0"
-
-/* Define to the one symbol short name of this package. */
-#define PACKAGE_TARNAME "scrypt"
-
-/* Define to the version of this package. */
-#define PACKAGE_VERSION "1.2.0"
-
-/* Define to 1 if you have the ANSI C header files. */
-#define STDC_HEADERS 1
-
-/* Version number of package */
-#define VERSION "1.2.0"
-
-/* Number of bits in a file offset, on hosts where this is settable. */
-/* #undef _FILE_OFFSET_BITS */
-
-/* Define for large files, on AIX-style hosts. */
-/* #undef _LARGE_FILES */
diff -pruN 0.8.0-0.3/scrypt-1.2.0/lib/crypto/crypto_scrypt.c 0.8.20-1/scrypt-1.2.0/lib/crypto/crypto_scrypt.c
--- 0.8.0-0.3/scrypt-1.2.0/lib/crypto/crypto_scrypt.c	2016-09-17 12:31:26.000000000 +0000
+++ 0.8.20-1/scrypt-1.2.0/lib/crypto/crypto_scrypt.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,255 +0,0 @@
-/*-
- * Copyright 2009 Colin Percival
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * This file was originally written by Colin Percival as part of the Tarsnap
- * online backup system.
- */
-#include "scrypt_platform.h"
-
-#include <sys/types.h>
-
-#ifndef _WIN32
-#include <sys/mman.h>
-#endif
-
-#include <errno.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "cpusupport.h"
-#include "sha256.h"
-#include "warnp.h"
-
-#include "crypto_scrypt_smix.h"
-#include "crypto_scrypt_smix_sse2.h"
-
-#include "crypto_scrypt.h"
-
-static void (*smix_func)(uint8_t *, size_t, uint64_t, void *, void *) = NULL;
-
-/**
- * _crypto_scrypt(passwd, passwdlen, salt, saltlen, N, r, p, buf, buflen, smix):
- * Perform the requested scrypt computation, using ${smix} as the smix routine.
- */
-static int
-_crypto_scrypt(const uint8_t * passwd, size_t passwdlen,
-    const uint8_t * salt, size_t saltlen, uint64_t N, uint32_t _r, uint32_t _p,
-    uint8_t * buf, size_t buflen,
-    void (*smix)(uint8_t *, size_t, uint64_t, void *, void *))
-{
-	void * B0, * V0, * XY0;
-	uint8_t * B;
-	uint32_t * V;
-	uint32_t * XY;
-	size_t r = _r, p = _p;
-	uint32_t i;
-
-	/* Sanity-check parameters. */
-#if SIZE_MAX > UINT32_MAX
-	if (buflen > (((uint64_t)(1) << 32) - 1) * 32) {
-		errno = EFBIG;
-		goto err0;
-	}
-#endif
-	if ((uint64_t)(r) * (uint64_t)(p) >= (1 << 30)) {
-		errno = EFBIG;
-		goto err0;
-	}
-	if (((N & (N - 1)) != 0) || (N < 2)) {
-		errno = EINVAL;
-		goto err0;
-	}
-	if ((r > SIZE_MAX / 128 / p) ||
-#if SIZE_MAX / 256 <= UINT32_MAX
-	    (r > (SIZE_MAX - 64) / 256) ||
-#endif
-	    (N > SIZE_MAX / 128 / r)) {
-		errno = ENOMEM;
-		goto err0;
-	}
-
-	/* Allocate memory. */
-#ifdef HAVE_POSIX_MEMALIGN
-	if ((errno = posix_memalign(&B0, 64, 128 * r * p)) != 0)
-		goto err0;
-	B = (uint8_t *)(B0);
-	if ((errno = posix_memalign(&XY0, 64, 256 * r + 64)) != 0)
-		goto err1;
-	XY = (uint32_t *)(XY0);
-#if !defined(MAP_ANON) || !defined(HAVE_MMAP)
-	if ((errno = posix_memalign(&V0, 64, 128 * r * N)) != 0)
-		goto err2;
-	V = (uint32_t *)(V0);
-#endif
-#else
-	if ((B0 = malloc(128 * r * p + 63)) == NULL)
-		goto err0;
-	B = (uint8_t *)(((uintptr_t)(B0) + 63) & ~ (uintptr_t)(63));
-	if ((XY0 = malloc(256 * r + 64 + 63)) == NULL)
-		goto err1;
-	XY = (uint32_t *)(((uintptr_t)(XY0) + 63) & ~ (uintptr_t)(63));
-#if !defined(MAP_ANON) || !defined(HAVE_MMAP)
-	if ((V0 = malloc(128 * r * N + 63)) == NULL)
-		goto err2;
-	V = (uint32_t *)(((uintptr_t)(V0) + 63) & ~ (uintptr_t)(63));
-#endif
-#endif
-#if defined(MAP_ANON) && defined(HAVE_MMAP)
-	if ((V0 = mmap(NULL, 128 * r * N, PROT_READ | PROT_WRITE,
-#ifdef MAP_NOCORE
-	    MAP_ANON | MAP_PRIVATE | MAP_NOCORE,
-#else
-	    MAP_ANON | MAP_PRIVATE,
-#endif
-	    -1, 0)) == MAP_FAILED)
-		goto err2;
-	V = (uint32_t *)(V0);
-#endif
-
-	/* 1: (B_0 ... B_{p-1}) <-- PBKDF2(P, S, 1, p * MFLen) */
-	PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, 1, B, p * 128 * r);
-
-	/* 2: for i = 0 to p - 1 do */
-	for (i = 0; i < p; i++) {
-		/* 3: B_i <-- MF(B_i, N) */
-		(smix)(&B[i * 128 * r], r, N, V, XY);
-	}
-
-	/* 5: DK <-- PBKDF2(P, B, 1, dkLen) */
-	PBKDF2_SHA256(passwd, passwdlen, B, p * 128 * r, 1, buf, buflen);
-
-	/* Free memory. */
-#if defined(MAP_ANON) && defined(HAVE_MMAP)
-	if (munmap(V0, 128 * r * N))
-		goto err2;
-#else
-	free(V0);
-#endif
-	free(XY0);
-	free(B0);
-
-	/* Success! */
-	return (0);
-
-err2:
-	free(XY0);
-err1:
-	free(B0);
-err0:
-	/* Failure! */
-	return (-1);
-}
-
-#define TESTLEN 64
-static struct scrypt_test {
-	const char * passwd;
-	const char * salt;
-	uint64_t N;
-	uint32_t r;
-	uint32_t p;
-	uint8_t result[TESTLEN];
-} testcase = {
-	"pleaseletmein",
-	"SodiumChloride",
-	16,
-	8,
-	1,
-	{
-		0x25, 0xa9, 0xfa, 0x20, 0x7f, 0x87, 0xca, 0x09,
-		0xa4, 0xef, 0x8b, 0x9f, 0x77, 0x7a, 0xca, 0x16,
-		0xbe, 0xb7, 0x84, 0xae, 0x18, 0x30, 0xbf, 0xbf,
-		0xd3, 0x83, 0x25, 0xaa, 0xbb, 0x93, 0x77, 0xdf,
-		0x1b, 0xa7, 0x84, 0xd7, 0x46, 0xea, 0x27, 0x3b,
-		0xf5, 0x16, 0xa4, 0x6f, 0xbf, 0xac, 0xf5, 0x11,
-		0xc5, 0xbe, 0xba, 0x4c, 0x4a, 0xb3, 0xac, 0xc7,
-		0xfa, 0x6f, 0x46, 0x0b, 0x6c, 0x0f, 0x47, 0x7b,
-	}
-};
-
-static int
-testsmix(void (*smix)(uint8_t *, size_t, uint64_t, void *, void *))
-{
-	uint8_t hbuf[TESTLEN];
-
-	/* Perform the computation. */
-	if (_crypto_scrypt(
-	    (const uint8_t *)testcase.passwd, strlen(testcase.passwd),
-	    (const uint8_t *)testcase.salt, strlen(testcase.salt),
-	    testcase.N, testcase.r, testcase.p, hbuf, TESTLEN, smix))
-		return (-1);
-
-	/* Does it match? */
-	return (memcmp(testcase.result, hbuf, TESTLEN));
-}
-
-static void
-selectsmix(void)
-{
-
-#ifdef CPUSUPPORT_X86_SSE2
-	/* If we're running on an SSE2-capable CPU, try that code. */
-	if (cpusupport_x86_sse2()) {
-		/* If SSE2ized smix works, use it. */
-		if (!testsmix(crypto_scrypt_smix_sse2)) {
-			smix_func = crypto_scrypt_smix_sse2;
-			return;
-		}
-		warn0("Disabling broken SSE2 scrypt support - please report bug!");
-	}
-#endif
-
-	/* If generic smix works, use it. */
-	if (!testsmix(crypto_scrypt_smix)) {
-		smix_func = crypto_scrypt_smix;
-		return;
-	}
-	warn0("Generic scrypt code is broken - please report bug!");
-
-	/* If we get here, something really bad happened. */
-	abort();
-}
-
-/**
- * crypto_scrypt(passwd, passwdlen, salt, saltlen, N, r, p, buf, buflen):
- * Compute scrypt(passwd[0 .. passwdlen - 1], salt[0 .. saltlen - 1], N, r,
- * p, buflen) and write the result into buf.  The parameters r, p, and buflen
- * must satisfy r * p < 2^30 and buflen <= (2^32 - 1) * 32.  The parameter N
- * must be a power of 2 greater than 1.
- *
- * Return 0 on success; or -1 on error.
- */
-int
-crypto_scrypt(const uint8_t * passwd, size_t passwdlen,
-    const uint8_t * salt, size_t saltlen, uint64_t N, uint32_t _r, uint32_t _p,
-    uint8_t * buf, size_t buflen)
-{
-
-	if (smix_func == NULL)
-		selectsmix();
-
-	return (_crypto_scrypt(passwd, passwdlen, salt, saltlen, N, _r, _p,
-	    buf, buflen, smix_func));
-}
diff -pruN 0.8.0-0.3/scrypt-1.2.0/lib/crypto/crypto_scrypt.h 0.8.20-1/scrypt-1.2.0/lib/crypto/crypto_scrypt.h
--- 0.8.0-0.3/scrypt-1.2.0/lib/crypto/crypto_scrypt.h	2015-08-08 18:45:05.000000000 +0000
+++ 0.8.20-1/scrypt-1.2.0/lib/crypto/crypto_scrypt.h	1970-01-01 00:00:00.000000000 +0000
@@ -1,47 +0,0 @@
-/*-
- * Copyright 2009 Colin Percival
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * This file was originally written by Colin Percival as part of the Tarsnap
- * online backup system.
- */
-#ifndef _CRYPTO_SCRYPT_H_
-#define _CRYPTO_SCRYPT_H_
-
-#include <stdint.h>
-#include <unistd.h>
-
-/**
- * crypto_scrypt(passwd, passwdlen, salt, saltlen, N, r, p, buf, buflen):
- * Compute scrypt(passwd[0 .. passwdlen - 1], salt[0 .. saltlen - 1], N, r,
- * p, buflen) and write the result into buf.  The parameters r, p, and buflen
- * must satisfy r * p < 2^30 and buflen <= (2^32 - 1) * 32.  The parameter N
- * must be a power of 2 greater than 1.
- *
- * Return 0 on success; or -1 on error.
- */
-int crypto_scrypt(const uint8_t *, size_t, const uint8_t *, size_t, uint64_t,
-    uint32_t, uint32_t, uint8_t *, size_t);
-
-#endif /* !_CRYPTO_SCRYPT_H_ */
diff -pruN 0.8.0-0.3/scrypt-1.2.0/lib/crypto/crypto_scrypt_smix.c 0.8.20-1/scrypt-1.2.0/lib/crypto/crypto_scrypt_smix.c
--- 0.8.0-0.3/scrypt-1.2.0/lib/crypto/crypto_scrypt_smix.c	2015-08-08 18:45:05.000000000 +0000
+++ 0.8.20-1/scrypt-1.2.0/lib/crypto/crypto_scrypt_smix.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,215 +0,0 @@
-/*-
- * Copyright 2009 Colin Percival
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * This file was originally written by Colin Percival as part of the Tarsnap
- * online backup system.
- */
-#include <stdint.h>
-#include <string.h>
-
-#include "sha256.h"
-#include "sysendian.h"
-
-#include "crypto_scrypt_smix.h"
-
-static void blkcpy(void *, const void *, size_t);
-static void blkxor(void *, const void *, size_t);
-static void salsa20_8(uint32_t[16]);
-static void blockmix_salsa8(const uint32_t *, uint32_t *, uint32_t *, size_t);
-static uint64_t integerify(const void *, size_t);
-
-static void
-blkcpy(void * dest, const void * src, size_t len)
-{
-	size_t * D = dest;
-	const size_t * S = src;
-	size_t L = len / sizeof(size_t);
-	size_t i;
-
-	for (i = 0; i < L; i++)
-		D[i] = S[i];
-}
-
-static void
-blkxor(void * dest, const void * src, size_t len)
-{
-	size_t * D = dest;
-	const size_t * S = src;
-	size_t L = len / sizeof(size_t);
-	size_t i;
-
-	for (i = 0; i < L; i++)
-		D[i] ^= S[i];
-}
-
-/**
- * salsa20_8(B):
- * Apply the salsa20/8 core to the provided block.
- */
-static void
-salsa20_8(uint32_t B[16])
-{
-	uint32_t x[16];
-	size_t i;
-
-	blkcpy(x, B, 64);
-	for (i = 0; i < 8; i += 2) {
-#define R(a,b) (((a) << (b)) | ((a) >> (32 - (b))))
-		/* Operate on columns. */
-		x[ 4] ^= R(x[ 0]+x[12], 7);  x[ 8] ^= R(x[ 4]+x[ 0], 9);
-		x[12] ^= R(x[ 8]+x[ 4],13);  x[ 0] ^= R(x[12]+x[ 8],18);
-
-		x[ 9] ^= R(x[ 5]+x[ 1], 7);  x[13] ^= R(x[ 9]+x[ 5], 9);
-		x[ 1] ^= R(x[13]+x[ 9],13);  x[ 5] ^= R(x[ 1]+x[13],18);
-
-		x[14] ^= R(x[10]+x[ 6], 7);  x[ 2] ^= R(x[14]+x[10], 9);
-		x[ 6] ^= R(x[ 2]+x[14],13);  x[10] ^= R(x[ 6]+x[ 2],18);
-
-		x[ 3] ^= R(x[15]+x[11], 7);  x[ 7] ^= R(x[ 3]+x[15], 9);
-		x[11] ^= R(x[ 7]+x[ 3],13);  x[15] ^= R(x[11]+x[ 7],18);
-
-		/* Operate on rows. */
-		x[ 1] ^= R(x[ 0]+x[ 3], 7);  x[ 2] ^= R(x[ 1]+x[ 0], 9);
-		x[ 3] ^= R(x[ 2]+x[ 1],13);  x[ 0] ^= R(x[ 3]+x[ 2],18);
-
-		x[ 6] ^= R(x[ 5]+x[ 4], 7);  x[ 7] ^= R(x[ 6]+x[ 5], 9);
-		x[ 4] ^= R(x[ 7]+x[ 6],13);  x[ 5] ^= R(x[ 4]+x[ 7],18);
-
-		x[11] ^= R(x[10]+x[ 9], 7);  x[ 8] ^= R(x[11]+x[10], 9);
-		x[ 9] ^= R(x[ 8]+x[11],13);  x[10] ^= R(x[ 9]+x[ 8],18);
-
-		x[12] ^= R(x[15]+x[14], 7);  x[13] ^= R(x[12]+x[15], 9);
-		x[14] ^= R(x[13]+x[12],13);  x[15] ^= R(x[14]+x[13],18);
-#undef R
-	}
-	for (i = 0; i < 16; i++)
-		B[i] += x[i];
-}
-
-/**
- * blockmix_salsa8(Bin, Bout, X, r):
- * Compute Bout = BlockMix_{salsa20/8, r}(Bin).  The input Bin must be 128r
- * bytes in length; the output Bout must also be the same size.  The
- * temporary space X must be 64 bytes.
- */
-static void
-blockmix_salsa8(const uint32_t * Bin, uint32_t * Bout, uint32_t * X, size_t r)
-{
-	size_t i;
-
-	/* 1: X <-- B_{2r - 1} */
-	blkcpy(X, &Bin[(2 * r - 1) * 16], 64);
-
-	/* 2: for i = 0 to 2r - 1 do */
-	for (i = 0; i < 2 * r; i += 2) {
-		/* 3: X <-- H(X \xor B_i) */
-		blkxor(X, &Bin[i * 16], 64);
-		salsa20_8(X);
-
-		/* 4: Y_i <-- X */
-		/* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */
-		blkcpy(&Bout[i * 8], X, 64);
-
-		/* 3: X <-- H(X \xor B_i) */
-		blkxor(X, &Bin[i * 16 + 16], 64);
-		salsa20_8(X);
-
-		/* 4: Y_i <-- X */
-		/* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */
-		blkcpy(&Bout[i * 8 + r * 16], X, 64);
-	}
-}
-
-/**
- * integerify(B, r):
- * Return the result of parsing B_{2r-1} as a little-endian integer.
- */
-static uint64_t
-integerify(const void * B, size_t r)
-{
-	const uint32_t * X = (const void *)((uintptr_t)(B) + (2 * r - 1) * 64);
-
-	return (((uint64_t)(X[1]) << 32) + X[0]);
-}
-
-/**
- * crypto_scrypt_smix(B, r, N, V, XY):
- * Compute B = SMix_r(B, N).  The input B must be 128r bytes in length;
- * the temporary storage V must be 128rN bytes in length; the temporary
- * storage XY must be 256r + 64 bytes in length.  The value N must be a
- * power of 2 greater than 1.  The arrays B, V, and XY must be aligned to a
- * multiple of 64 bytes.
- */
-void
-crypto_scrypt_smix(uint8_t * B, size_t r, uint64_t N, void * _V, void * XY)
-{
-	uint32_t * X = XY;
-	uint32_t * Y = (void *)((uint8_t *)(XY) + 128 * r);
-	uint32_t * Z = (void *)((uint8_t *)(XY) + 256 * r);
-	uint32_t * V = _V;
-	uint64_t i;
-	uint64_t j;
-	size_t k;
-
-	/* 1: X <-- B */
-	for (k = 0; k < 32 * r; k++)
-		X[k] = le32dec(&B[4 * k]);
-
-	/* 2: for i = 0 to N - 1 do */
-	for (i = 0; i < N; i += 2) {
-		/* 3: V_i <-- X */
-		blkcpy(&V[i * (32 * r)], X, 128 * r);
-
-		/* 4: X <-- H(X) */
-		blockmix_salsa8(X, Y, Z, r);
-
-		/* 3: V_i <-- X */
-		blkcpy(&V[(i + 1) * (32 * r)], Y, 128 * r);
-
-		/* 4: X <-- H(X) */
-		blockmix_salsa8(Y, X, Z, r);
-	}
-
-	/* 6: for i = 0 to N - 1 do */
-	for (i = 0; i < N; i += 2) {
-		/* 7: j <-- Integerify(X) mod N */
-		j = integerify(X, r) & (N - 1);
-
-		/* 8: X <-- H(X \xor V_j) */
-		blkxor(X, &V[j * (32 * r)], 128 * r);
-		blockmix_salsa8(X, Y, Z, r);
-
-		/* 7: j <-- Integerify(X) mod N */
-		j = integerify(Y, r) & (N - 1);
-
-		/* 8: X <-- H(X \xor V_j) */
-		blkxor(Y, &V[j * (32 * r)], 128 * r);
-		blockmix_salsa8(Y, X, Z, r);
-	}
-
-	/* 10: B' <-- X */
-	for (k = 0; k < 32 * r; k++)
-		le32enc(&B[4 * k], X[k]);
-}
diff -pruN 0.8.0-0.3/scrypt-1.2.0/lib/crypto/crypto_scrypt_smix.h 0.8.20-1/scrypt-1.2.0/lib/crypto/crypto_scrypt_smix.h
--- 0.8.0-0.3/scrypt-1.2.0/lib/crypto/crypto_scrypt_smix.h	2015-08-08 18:45:05.000000000 +0000
+++ 0.8.20-1/scrypt-1.2.0/lib/crypto/crypto_scrypt_smix.h	1970-01-01 00:00:00.000000000 +0000
@@ -1,14 +0,0 @@
-#ifndef _CRYPTO_SCRYPT_SMIX_H_
-#define _CRYPTO_SCRYPT_SMIX_H_
-
-/**
- * crypto_scrypt_smix(B, r, N, V, XY):
- * Compute B = SMix_r(B, N).  The input B must be 128r bytes in length;
- * the temporary storage V must be 128rN bytes in length; the temporary
- * storage XY must be 256r + 64 bytes in length.  The value N must be a
- * power of 2 greater than 1.  The arrays B, V, and XY must be aligned to a
- * multiple of 64 bytes.
- */
-void crypto_scrypt_smix(uint8_t *, size_t, uint64_t, void *, void *);
-
-#endif /* !_CRYPTO_SCRYPT_SMIX_H_ */
diff -pruN 0.8.0-0.3/scrypt-1.2.0/lib/crypto/crypto_scrypt_smix_sse2.c 0.8.20-1/scrypt-1.2.0/lib/crypto/crypto_scrypt_smix_sse2.c
--- 0.8.0-0.3/scrypt-1.2.0/lib/crypto/crypto_scrypt_smix_sse2.c	2015-08-08 18:45:05.000000000 +0000
+++ 0.8.20-1/scrypt-1.2.0/lib/crypto/crypto_scrypt_smix_sse2.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,247 +0,0 @@
-/*-
- * Copyright 2009 Colin Percival
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * This file was originally written by Colin Percival as part of the Tarsnap
- * online backup system.
- */
-#include "cpusupport.h"
-#ifdef CPUSUPPORT_X86_SSE2
-
-#include <emmintrin.h>
-#include <stdint.h>
-
-#include "sysendian.h"
-
-#include "crypto_scrypt_smix_sse2.h"
-
-static void blkcpy(void *, const void *, size_t);
-static void blkxor(void *, const void *, size_t);
-static void salsa20_8(__m128i *);
-static void blockmix_salsa8(const __m128i *, __m128i *, __m128i *, size_t);
-static uint64_t integerify(const void *, size_t);
-
-static void
-blkcpy(void * dest, const void * src, size_t len)
-{
-	__m128i * D = dest;
-	const __m128i * S = src;
-	size_t L = len / 16;
-	size_t i;
-
-	for (i = 0; i < L; i++)
-		D[i] = S[i];
-}
-
-static void
-blkxor(void * dest, const void * src, size_t len)
-{
-	__m128i * D = dest;
-	const __m128i * S = src;
-	size_t L = len / 16;
-	size_t i;
-
-	for (i = 0; i < L; i++)
-		D[i] = _mm_xor_si128(D[i], S[i]);
-}
-
-/**
- * salsa20_8(B):
- * Apply the salsa20/8 core to the provided block.
- */
-static void
-salsa20_8(__m128i B[4])
-{
-	__m128i X0, X1, X2, X3;
-	__m128i T;
-	size_t i;
-
-	X0 = B[0];
-	X1 = B[1];
-	X2 = B[2];
-	X3 = B[3];
-
-	for (i = 0; i < 8; i += 2) {
-		/* Operate on "columns". */
-		T = _mm_add_epi32(X0, X3);
-		X1 = _mm_xor_si128(X1, _mm_slli_epi32(T, 7));
-		X1 = _mm_xor_si128(X1, _mm_srli_epi32(T, 25));
-		T = _mm_add_epi32(X1, X0);
-		X2 = _mm_xor_si128(X2, _mm_slli_epi32(T, 9));
-		X2 = _mm_xor_si128(X2, _mm_srli_epi32(T, 23));
-		T = _mm_add_epi32(X2, X1);
-		X3 = _mm_xor_si128(X3, _mm_slli_epi32(T, 13));
-		X3 = _mm_xor_si128(X3, _mm_srli_epi32(T, 19));
-		T = _mm_add_epi32(X3, X2);
-		X0 = _mm_xor_si128(X0, _mm_slli_epi32(T, 18));
-		X0 = _mm_xor_si128(X0, _mm_srli_epi32(T, 14));
-
-		/* Rearrange data. */
-		X1 = _mm_shuffle_epi32(X1, 0x93);
-		X2 = _mm_shuffle_epi32(X2, 0x4E);
-		X3 = _mm_shuffle_epi32(X3, 0x39);
-
-		/* Operate on "rows". */
-		T = _mm_add_epi32(X0, X1);
-		X3 = _mm_xor_si128(X3, _mm_slli_epi32(T, 7));
-		X3 = _mm_xor_si128(X3, _mm_srli_epi32(T, 25));
-		T = _mm_add_epi32(X3, X0);
-		X2 = _mm_xor_si128(X2, _mm_slli_epi32(T, 9));
-		X2 = _mm_xor_si128(X2, _mm_srli_epi32(T, 23));
-		T = _mm_add_epi32(X2, X3);
-		X1 = _mm_xor_si128(X1, _mm_slli_epi32(T, 13));
-		X1 = _mm_xor_si128(X1, _mm_srli_epi32(T, 19));
-		T = _mm_add_epi32(X1, X2);
-		X0 = _mm_xor_si128(X0, _mm_slli_epi32(T, 18));
-		X0 = _mm_xor_si128(X0, _mm_srli_epi32(T, 14));
-
-		/* Rearrange data. */
-		X1 = _mm_shuffle_epi32(X1, 0x39);
-		X2 = _mm_shuffle_epi32(X2, 0x4E);
-		X3 = _mm_shuffle_epi32(X3, 0x93);
-	}
-
-	B[0] = _mm_add_epi32(B[0], X0);
-	B[1] = _mm_add_epi32(B[1], X1);
-	B[2] = _mm_add_epi32(B[2], X2);
-	B[3] = _mm_add_epi32(B[3], X3);
-}
-
-/**
- * blockmix_salsa8(Bin, Bout, X, r):
- * Compute Bout = BlockMix_{salsa20/8, r}(Bin).  The input Bin must be 128r
- * bytes in length; the output Bout must also be the same size.  The
- * temporary space X must be 64 bytes.
- */
-static void
-blockmix_salsa8(const __m128i * Bin, __m128i * Bout, __m128i * X, size_t r)
-{
-	size_t i;
-
-	/* 1: X <-- B_{2r - 1} */
-	blkcpy(X, &Bin[8 * r - 4], 64);
-
-	/* 2: for i = 0 to 2r - 1 do */
-	for (i = 0; i < r; i++) {
-		/* 3: X <-- H(X \xor B_i) */
-		blkxor(X, &Bin[i * 8], 64);
-		salsa20_8(X);
-
-		/* 4: Y_i <-- X */
-		/* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */
-		blkcpy(&Bout[i * 4], X, 64);
-
-		/* 3: X <-- H(X \xor B_i) */
-		blkxor(X, &Bin[i * 8 + 4], 64);
-		salsa20_8(X);
-
-		/* 4: Y_i <-- X */
-		/* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */
-		blkcpy(&Bout[(r + i) * 4], X, 64);
-	}
-}
-
-/**
- * integerify(B, r):
- * Return the result of parsing B_{2r-1} as a little-endian integer.
- */
-static uint64_t
-integerify(const void * B, size_t r)
-{
-	const uint32_t * X = (const void *)((uintptr_t)(B) + (2 * r - 1) * 64);
-
-	return (((uint64_t)(X[13]) << 32) + X[0]);
-}
-
-/**
- * crypto_scrypt_smix_sse2(B, r, N, V, XY):
- * Compute B = SMix_r(B, N).  The input B must be 128r bytes in length;
- * the temporary storage V must be 128rN bytes in length; the temporary
- * storage XY must be 256r + 64 bytes in length.  The value N must be a
- * power of 2 greater than 1.  The arrays B, V, and XY must be aligned to a
- * multiple of 64 bytes.
- *
- * Use SSE2 instructions.
- */
-void
-crypto_scrypt_smix_sse2(uint8_t * B, size_t r, uint64_t N, void * V, void * XY)
-{
-	__m128i * X = XY;
-	__m128i * Y = (void *)((uintptr_t)(XY) + 128 * r);
-	__m128i * Z = (void *)((uintptr_t)(XY) + 256 * r);
-	uint32_t * X32 = (void *)X;
-	uint64_t i, j;
-	size_t k;
-
-	/* 1: X <-- B */
-	for (k = 0; k < 2 * r; k++) {
-		for (i = 0; i < 16; i++) {
-			X32[k * 16 + i] =
-			    le32dec(&B[(k * 16 + (i * 5 % 16)) * 4]);
-		}
-	}
-
-	/* 2: for i = 0 to N - 1 do */
-	for (i = 0; i < N; i += 2) {
-		/* 3: V_i <-- X */
-		blkcpy((void *)((uintptr_t)(V) + i * 128 * r), X, 128 * r);
-
-		/* 4: X <-- H(X) */
-		blockmix_salsa8(X, Y, Z, r);
-
-		/* 3: V_i <-- X */
-		blkcpy((void *)((uintptr_t)(V) + (i + 1) * 128 * r),
-		    Y, 128 * r);
-
-		/* 4: X <-- H(X) */
-		blockmix_salsa8(Y, X, Z, r);
-	}
-
-	/* 6: for i = 0 to N - 1 do */
-	for (i = 0; i < N; i += 2) {
-		/* 7: j <-- Integerify(X) mod N */
-		j = integerify(X, r) & (N - 1);
-
-		/* 8: X <-- H(X \xor V_j) */
-		blkxor(X, (void *)((uintptr_t)(V) + j * 128 * r), 128 * r);
-		blockmix_salsa8(X, Y, Z, r);
-
-		/* 7: j <-- Integerify(X) mod N */
-		j = integerify(Y, r) & (N - 1);
-
-		/* 8: X <-- H(X \xor V_j) */
-		blkxor(Y, (void *)((uintptr_t)(V) + j * 128 * r), 128 * r);
-		blockmix_salsa8(Y, X, Z, r);
-	}
-
-	/* 10: B' <-- X */
-	for (k = 0; k < 2 * r; k++) {
-		for (i = 0; i < 16; i++) {
-			le32enc(&B[(k * 16 + (i * 5 % 16)) * 4],
-			    X32[k * 16 + i]);
-		}
-	}
-}
-
-#endif /* CPUSUPPORT_X86_SSE2 */
diff -pruN 0.8.0-0.3/scrypt-1.2.0/lib/crypto/crypto_scrypt_smix_sse2.h 0.8.20-1/scrypt-1.2.0/lib/crypto/crypto_scrypt_smix_sse2.h
--- 0.8.0-0.3/scrypt-1.2.0/lib/crypto/crypto_scrypt_smix_sse2.h	2015-08-08 18:45:05.000000000 +0000
+++ 0.8.20-1/scrypt-1.2.0/lib/crypto/crypto_scrypt_smix_sse2.h	1970-01-01 00:00:00.000000000 +0000
@@ -1,16 +0,0 @@
-#ifndef _CRYPTO_SCRYPT_SMIX_SSE2_H_
-#define _CRYPTO_SCRYPT_SMIX_SSE2_H_
-
-/**
- * crypto_scrypt_smix_sse2(B, r, N, V, XY):
- * Compute B = SMix_r(B, N).  The input B must be 128r bytes in length;
- * the temporary storage V must be 128rN bytes in length; the temporary
- * storage XY must be 256r + 64 bytes in length.  The value N must be a
- * power of 2 greater than 1.  The arrays B, V, and XY must be aligned to a
- * multiple of 64 bytes.
- *
- * Use SSE2 instructions.
- */
-void crypto_scrypt_smix_sse2(uint8_t *, size_t, uint64_t, void *, void *);
-
-#endif /* !_CRYPTO_SCRYPT_SMIX_SSE2_H_ */
diff -pruN 0.8.0-0.3/scrypt-1.2.0/lib/scryptenc/scryptenc.c 0.8.20-1/scrypt-1.2.0/lib/scryptenc/scryptenc.c
--- 0.8.0-0.3/scrypt-1.2.0/lib/scryptenc/scryptenc.c	2015-08-08 18:45:05.000000000 +0000
+++ 0.8.20-1/scrypt-1.2.0/lib/scryptenc/scryptenc.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,569 +0,0 @@
-/*-
- * Copyright 2009 Colin Percival
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * This file was originally written by Colin Percival as part of the Tarsnap
- * online backup system.
- */
-#include "scrypt_platform.h"
-
-#include <errno.h>
-#include <fcntl.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "crypto_aes.h"
-#include "crypto_aesctr.h"
-#include "crypto_entropy.h"
-#include "insecure_memzero.h"
-#include "sha256.h"
-#include "sysendian.h"
-
-#include "crypto_scrypt.h"
-#include "memlimit.h"
-#include "scryptenc_cpuperf.h"
-
-#include "scryptenc.h"
-
-#define ENCBLOCK 65536
-
-static int pickparams(size_t, double, double,
-    int *, uint32_t *, uint32_t *);
-static int checkparams(size_t, double, double, int, uint32_t, uint32_t);
-
-static int
-pickparams(size_t maxmem, double maxmemfrac, double maxtime,
-    int * logN, uint32_t * r, uint32_t * p)
-{
-	size_t memlimit;
-	double opps;
-	double opslimit;
-	double maxN, maxrp;
-	int rc;
-
-	/* Figure out how much memory to use. */
-	if (memtouse(maxmem, maxmemfrac, &memlimit))
-		return (1);
-
-	/* Figure out how fast the CPU is. */
-	if ((rc = scryptenc_cpuperf(&opps)) != 0)
-		return (rc);
-	opslimit = opps * maxtime;
-
-	/* Allow a minimum of 2^15 salsa20/8 cores. */
-	if (opslimit < 32768)
-		opslimit = 32768;
-
-	/* Fix r = 8 for now. */
-	*r = 8;
-
-	/*
-	 * The memory limit requires that 128Nr <= memlimit, while the CPU
-	 * limit requires that 4Nrp <= opslimit.  If opslimit < memlimit/32,
-	 * opslimit imposes the stronger limit on N.
-	 */
-#ifdef DEBUG
-	fprintf(stderr, "Requiring 128Nr <= %zu, 4Nrp <= %f\n",
-	    memlimit, opslimit);
-#endif
-	if (opslimit < memlimit/32) {
-		/* Set p = 1 and choose N based on the CPU limit. */
-		*p = 1;
-		maxN = opslimit / (*r * 4);
-		for (*logN = 1; *logN < 63; *logN += 1) {
-			if ((uint64_t)(1) << *logN > maxN / 2)
-				break;
-		}
-	} else {
-		/* Set N based on the memory limit. */
-		maxN = memlimit / (*r * 128);
-		for (*logN = 1; *logN < 63; *logN += 1) {
-			if ((uint64_t)(1) << *logN > maxN / 2)
-				break;
-		}
-
-		/* Choose p based on the CPU limit. */
-		maxrp = (opslimit / 4) / ((uint64_t)(1) << *logN);
-		if (maxrp > 0x3fffffff)
-			maxrp = 0x3fffffff;
-		*p = (uint32_t)(maxrp) / *r;
-	}
-
-#ifdef DEBUG
-	fprintf(stderr, "N = %zu r = %d p = %d\n",
-	    (size_t)(1) << *logN, (int)(*r), (int)(*p));
-#endif
-
-	/* Success! */
-	return (0);
-}
-
-static int
-checkparams(size_t maxmem, double maxmemfrac, double maxtime,
-    int logN, uint32_t r, uint32_t p)
-{
-	size_t memlimit;
-	double opps;
-	double opslimit;
-	uint64_t N;
-	int rc;
-
-	/* Figure out the maximum amount of memory we can use. */
-	if (memtouse(maxmem, maxmemfrac, &memlimit))
-		return (1);
-
-	/* Figure out how fast the CPU is. */
-	if ((rc = scryptenc_cpuperf(&opps)) != 0)
-		return (rc);
-	opslimit = opps * maxtime;
-
-	/* Sanity-check values. */
-	if ((logN < 1) || (logN > 63))
-		return (7);
-	if ((uint64_t)(r) * (uint64_t)(p) >= 0x40000000)
-		return (7);
-
-	/* Check limits. */
-	N = (uint64_t)(1) << logN;
-	if ((memlimit / N) / r < 128)
-		return (9);
-	if ((opslimit / N) / (r * p) < 4)
-		return (10);
-
-	/* Success! */
-	return (0);
-}
-
-static int
-scryptenc_setup(uint8_t header[96], uint8_t dk[64],
-    const uint8_t * passwd, size_t passwdlen,
-    size_t maxmem, double maxmemfrac, double maxtime)
-{
-	uint8_t salt[32];
-	uint8_t hbuf[32];
-	int logN;
-	uint64_t N;
-	uint32_t r;
-	uint32_t p;
-	SHA256_CTX ctx;
-	uint8_t * key_hmac = &dk[32];
-	HMAC_SHA256_CTX hctx;
-	int rc;
-
-	/* Pick values for N, r, p. */
-	if ((rc = pickparams(maxmem, maxmemfrac, maxtime,
-	    &logN, &r, &p)) != 0)
-		return (rc);
-	N = (uint64_t)(1) << logN;
-
-	/* Get some salt. */
-	if (crypto_entropy_read(salt, 32))
-		return (4);
-
-	/* Generate the derived keys. */
-	if (crypto_scrypt(passwd, passwdlen, salt, 32, N, r, p, dk, 64))
-		return (3);
-
-	/* Construct the file header. */
-	memcpy(header, "scrypt", 6);
-	header[6] = 0;
-	header[7] = logN;
-	be32enc(&header[8], r);
-	be32enc(&header[12], p);
-	memcpy(&header[16], salt, 32);
-
-	/* Add header checksum. */
-	SHA256_Init(&ctx);
-	SHA256_Update(&ctx, header, 48);
-	SHA256_Final(hbuf, &ctx);
-	memcpy(&header[48], hbuf, 16);
-
-	/* Add header signature (used for verifying password). */
-	HMAC_SHA256_Init(&hctx, key_hmac, 32);
-	HMAC_SHA256_Update(&hctx, header, 64);
-	HMAC_SHA256_Final(hbuf, &hctx);
-	memcpy(&header[64], hbuf, 32);
-
-	/* Success! */
-	return (0);
-}
-
-static int
-scryptdec_setup(const uint8_t header[96], uint8_t dk[64],
-    const uint8_t * passwd, size_t passwdlen,
-    size_t maxmem, double maxmemfrac, double maxtime)
-{
-	uint8_t salt[32];
-	uint8_t hbuf[32];
-	int logN;
-	uint32_t r;
-	uint32_t p;
-	uint64_t N;
-	SHA256_CTX ctx;
-	uint8_t * key_hmac = &dk[32];
-	HMAC_SHA256_CTX hctx;
-	int rc;
-
-	/* Parse N, r, p, salt. */
-	logN = header[7];
-	r = be32dec(&header[8]);
-	p = be32dec(&header[12]);
-	memcpy(salt, &header[16], 32);
-
-	/* Verify header checksum. */
-	SHA256_Init(&ctx);
-	SHA256_Update(&ctx, header, 48);
-	SHA256_Final(hbuf, &ctx);
-	if (memcmp(&header[48], hbuf, 16))
-		return (7);
-
-	/*
-	 * Check whether the provided parameters are valid and whether the
-	 * key derivation function can be computed within the allowed memory
-	 * and CPU time.
-	 */
-	if ((rc = checkparams(maxmem, maxmemfrac, maxtime, logN, r, p)) != 0)
-		return (rc);
-
-	/* Compute the derived keys. */
-	N = (uint64_t)(1) << logN;
-	if (crypto_scrypt(passwd, passwdlen, salt, 32, N, r, p, dk, 64))
-		return (3);
-
-	/* Check header signature (i.e., verify password). */
-	HMAC_SHA256_Init(&hctx, key_hmac, 32);
-	HMAC_SHA256_Update(&hctx, header, 64);
-	HMAC_SHA256_Final(hbuf, &hctx);
-	if (memcmp(hbuf, &header[64], 32))
-		return (11);
-
-	/* Success! */
-	return (0);
-}
-
-/**
- * scryptenc_buf(inbuf, inbuflen, outbuf, passwd, passwdlen,
- *     maxmem, maxmemfrac, maxtime):
- * Encrypt inbuflen bytes from inbuf, writing the resulting inbuflen + 128
- * bytes to outbuf.
- */
-int
-scryptenc_buf(const uint8_t * inbuf, size_t inbuflen, uint8_t * outbuf,
-    const uint8_t * passwd, size_t passwdlen,
-    size_t maxmem, double maxmemfrac, double maxtime)
-{
-	uint8_t dk[64];
-	uint8_t hbuf[32];
-	uint8_t header[96];
-	uint8_t * key_enc = dk;
-	uint8_t * key_hmac = &dk[32];
-	int rc;
-	HMAC_SHA256_CTX hctx;
-	struct crypto_aes_key * key_enc_exp;
-	struct crypto_aesctr * AES;
-
-	/* Generate the header and derived key. */
-	if ((rc = scryptenc_setup(header, dk, passwd, passwdlen,
-	    maxmem, maxmemfrac, maxtime)) != 0)
-		return (rc);
-
-	/* Copy header into output buffer. */
-	memcpy(outbuf, header, 96);
-
-	/* Encrypt data. */
-	if ((key_enc_exp = crypto_aes_key_expand(key_enc, 32)) == NULL)
-		return (5);
-	if ((AES = crypto_aesctr_init(key_enc_exp, 0)) == NULL)
-		return (6);
-	crypto_aesctr_stream(AES, inbuf, &outbuf[96], inbuflen);
-	crypto_aesctr_free(AES);
-	crypto_aes_key_free(key_enc_exp);
-
-	/* Add signature. */
-	HMAC_SHA256_Init(&hctx, key_hmac, 32);
-	HMAC_SHA256_Update(&hctx, outbuf, 96 + inbuflen);
-	HMAC_SHA256_Final(hbuf, &hctx);
-	memcpy(&outbuf[96 + inbuflen], hbuf, 32);
-
-	/* Zero sensitive data. */
-	insecure_memzero(dk, 64);
-
-	/* Success! */
-	return (0);
-}
-
-/**
- * scryptdec_buf(inbuf, inbuflen, outbuf, outlen, passwd, passwdlen,
- *     maxmem, maxmemfrac, maxtime):
- * Decrypt inbuflen bytes from inbuf, writing the result into outbuf and the
- * decrypted data length to outlen.  The allocated length of outbuf must
- * be at least inbuflen.
- */
-int
-scryptdec_buf(const uint8_t * inbuf, size_t inbuflen, uint8_t * outbuf,
-    size_t * outlen, const uint8_t * passwd, size_t passwdlen,
-    size_t maxmem, double maxmemfrac, double maxtime)
-{
-	uint8_t hbuf[32];
-	uint8_t dk[64];
-	uint8_t * key_enc = dk;
-	uint8_t * key_hmac = &dk[32];
-	int rc;
-	HMAC_SHA256_CTX hctx;
-	struct crypto_aes_key * key_enc_exp;
-	struct crypto_aesctr * AES;
-
-	/*
-	 * All versions of the scrypt format will start with "scrypt" and
-	 * have at least 7 bytes of header.
-	 */
-	if ((inbuflen < 7) || (memcmp(inbuf, "scrypt", 6) != 0))
-		return (7);
-
-	/* Check the format. */
-	if (inbuf[6] != 0)
-		return (8);
-
-	/* We must have at least 128 bytes. */
-	if (inbuflen < 128)
-		return (7);
-
-	/* Parse the header and generate derived keys. */
-	if ((rc = scryptdec_setup(inbuf, dk, passwd, passwdlen,
-	    maxmem, maxmemfrac, maxtime)) != 0)
-		return (rc);
-
-	/* Decrypt data. */
-	if ((key_enc_exp = crypto_aes_key_expand(key_enc, 32)) == NULL)
-		return (5);
-	if ((AES = crypto_aesctr_init(key_enc_exp, 0)) == NULL)
-		return (6);
-	crypto_aesctr_stream(AES, &inbuf[96], outbuf, inbuflen - 128);
-	crypto_aesctr_free(AES);
-	crypto_aes_key_free(key_enc_exp);
-	*outlen = inbuflen - 128;
-
-	/* Verify signature. */
-	HMAC_SHA256_Init(&hctx, key_hmac, 32);
-	HMAC_SHA256_Update(&hctx, inbuf, inbuflen - 32);
-	HMAC_SHA256_Final(hbuf, &hctx);
-	if (memcmp(hbuf, &inbuf[inbuflen - 32], 32))
-		return (7);
-
-	/* Zero sensitive data. */
-	insecure_memzero(dk, 64);
-
-	/* Success! */
-	return (0);
-}
-
-/**
- * scryptenc_file(infile, outfile, passwd, passwdlen,
- *     maxmem, maxmemfrac, maxtime):
- * Read a stream from infile and encrypt it, writing the resulting stream to
- * outfile.
- */
-int
-scryptenc_file(FILE * infile, FILE * outfile,
-    const uint8_t * passwd, size_t passwdlen,
-    size_t maxmem, double maxmemfrac, double maxtime)
-{
-	uint8_t buf[ENCBLOCK];
-	uint8_t dk[64];
-	uint8_t hbuf[32];
-	uint8_t header[96];
-	uint8_t * key_enc = dk;
-	uint8_t * key_hmac = &dk[32];
-	size_t readlen;
-	HMAC_SHA256_CTX hctx;
-	struct crypto_aes_key * key_enc_exp;
-	struct crypto_aesctr * AES;
-	int rc;
-
-	/* Generate the header and derived key. */
-	if ((rc = scryptenc_setup(header, dk, passwd, passwdlen,
-	    maxmem, maxmemfrac, maxtime)) != 0)
-		return (rc);
-
-	/* Hash and write the header. */
-	HMAC_SHA256_Init(&hctx, key_hmac, 32);
-	HMAC_SHA256_Update(&hctx, header, 96);
-	if (fwrite(header, 96, 1, outfile) != 1)
-		return (12);
-
-	/*
-	 * Read blocks of data, encrypt them, and write them out; hash the
-	 * data as it is produced.
-	 */
-	if ((key_enc_exp = crypto_aes_key_expand(key_enc, 32)) == NULL)
-		return (5);
-	if ((AES = crypto_aesctr_init(key_enc_exp, 0)) == NULL)
-		return (6);
-	do {
-		if ((readlen = fread(buf, 1, ENCBLOCK, infile)) == 0)
-			break;
-		crypto_aesctr_stream(AES, buf, buf, readlen);
-		HMAC_SHA256_Update(&hctx, buf, readlen);
-		if (fwrite(buf, 1, readlen, outfile) < readlen) {
-			crypto_aesctr_free(AES);
-			return (12);
-		}
-	} while (1);
-	crypto_aesctr_free(AES);
-	crypto_aes_key_free(key_enc_exp);
-
-	/* Did we exit the loop due to a read error? */
-	if (ferror(infile))
-		return (13);
-
-	/* Compute the final HMAC and output it. */
-	HMAC_SHA256_Final(hbuf, &hctx);
-	if (fwrite(hbuf, 32, 1, outfile) != 1)
-		return (12);
-
-	/* Zero sensitive data. */
-	insecure_memzero(dk, 64);
-
-	/* Success! */
-	return (0);
-}
-
-/**
- * scryptdec_file(infile, outfile, passwd, passwdlen,
- *     maxmem, maxmemfrac, maxtime):
- * Read a stream from infile and decrypt it, writing the resulting stream to
- * outfile.
- */
-int
-scryptdec_file(FILE * infile, FILE * outfile,
-    const uint8_t * passwd, size_t passwdlen,
-    size_t maxmem, double maxmemfrac, double maxtime)
-{
-	uint8_t buf[ENCBLOCK + 32];
-	uint8_t header[96];
-	uint8_t hbuf[32];
-	uint8_t dk[64];
-	uint8_t * key_enc = dk;
-	uint8_t * key_hmac = &dk[32];
-	size_t buflen = 0;
-	size_t readlen;
-	HMAC_SHA256_CTX hctx;
-	struct crypto_aes_key * key_enc_exp;
-	struct crypto_aesctr * AES;
-	int rc;
-
-	/*
-	 * Read the first 7 bytes of the file; all future versions of scrypt
-	 * are guaranteed to have at least 7 bytes of header.
-	 */
-	if (fread(header, 7, 1, infile) < 1) {
-		if (ferror(infile))
-			return (13);
-		else
-			return (7);
-	}
-
-	/* Do we have the right magic? */
-	if (memcmp(header, "scrypt", 6))
-		return (7);
-	if (header[6] != 0)
-		return (8);
-
-	/*
-	 * Read another 89 bytes of the file; version 0 of the scrypt file
-	 * format has a 96-byte header.
-	 */
-	if (fread(&header[7], 89, 1, infile) < 1) {
-		if (ferror(infile))
-			return (13);
-		else
-			return (7);
-	}
-
-	/* Parse the header and generate derived keys. */
-	if ((rc = scryptdec_setup(header, dk, passwd, passwdlen,
-	    maxmem, maxmemfrac, maxtime)) != 0)
-		return (rc);
-
-	/* Start hashing with the header. */
-	HMAC_SHA256_Init(&hctx, key_hmac, 32);
-	HMAC_SHA256_Update(&hctx, header, 96);
-
-	/*
-	 * We don't know how long the encrypted data block is (we can't know,
-	 * since data can be streamed into 'scrypt enc') so we need to read
-	 * data and decrypt all of it except the final 32 bytes, then check
-	 * if that final 32 bytes is the correct signature.
-	 */
-	if ((key_enc_exp = crypto_aes_key_expand(key_enc, 32)) == NULL)
-		return (5);
-	if ((AES = crypto_aesctr_init(key_enc_exp, 0)) == NULL)
-		return (6);
-	do {
-		/* Read data until we have more than 32 bytes of it. */
-		if ((readlen = fread(&buf[buflen], 1,
-		    ENCBLOCK + 32 - buflen, infile)) == 0)
-			break;
-		buflen += readlen;
-		if (buflen <= 32)
-			continue;
-
-		/*
-		 * Decrypt, hash, and output everything except the last 32
-		 * bytes out of what we have in our buffer.
-		 */
-		HMAC_SHA256_Update(&hctx, buf, buflen - 32);
-		crypto_aesctr_stream(AES, buf, buf, buflen - 32);
-		if (fwrite(buf, 1, buflen - 32, outfile) < buflen - 32) {
-			crypto_aesctr_free(AES);
-			return (12);
-		}
-
-		/* Move the last 32 bytes to the start of the buffer. */
-		memmove(buf, &buf[buflen - 32], 32);
-		buflen = 32;
-	} while (1);
-	crypto_aesctr_free(AES);
-	crypto_aes_key_free(key_enc_exp);
-
-	/* Did we exit the loop due to a read error? */
-	if (ferror(infile))
-		return (13);
-
-	/* Did we read enough data that we *might* have a valid signature? */
-	if (buflen < 32)
-		return (7);
-
-	/* Verify signature. */
-	HMAC_SHA256_Final(hbuf, &hctx);
-	if (memcmp(hbuf, buf, 32))
-		return (7);
-
-	/* Zero sensitive data. */
-	insecure_memzero(dk, 64);
-
-	return (0);
-}
diff -pruN 0.8.0-0.3/scrypt-1.2.0/lib/scryptenc/scryptenc_cpuperf.c 0.8.20-1/scrypt-1.2.0/lib/scryptenc/scryptenc_cpuperf.c
--- 0.8.0-0.3/scrypt-1.2.0/lib/scryptenc/scryptenc_cpuperf.c	2015-08-08 18:45:05.000000000 +0000
+++ 0.8.20-1/scrypt-1.2.0/lib/scryptenc/scryptenc_cpuperf.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,185 +0,0 @@
-/*-
- * Copyright 2009 Colin Percival
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * This file was originally written by Colin Percival as part of the Tarsnap
- * online backup system.
- */
-#include "scrypt_platform.h"
-
-#include <sys/time.h>
-
-#include <stdint.h>
-#include <stdio.h>
-#include <time.h>
-
-#include "crypto_scrypt.h"
-
-#include "scryptenc_cpuperf.h"
-
-#ifdef HAVE_CLOCK_GETTIME
-
-static clock_t clocktouse;
-
-static int
-getclockres(double * resd)
-{
-	struct timespec res;
-
-	/*
-	 * Try clocks in order of preference until we find one which works.
-	 * (We assume that if clock_getres works, clock_gettime will, too.)
-	 * The use of if/else/if/else/if/else rather than if/elif/elif/else
-	 * is ugly but legal, and allows us to #ifdef things appropriately.
-	 */
-#ifdef CLOCK_VIRTUAL
-	if (clock_getres(CLOCK_VIRTUAL, &res) == 0)
-		clocktouse = CLOCK_VIRTUAL;
-	else
-#endif
-#ifdef CLOCK_MONOTONIC
-	if (clock_getres(CLOCK_MONOTONIC, &res) == 0)
-		clocktouse = CLOCK_MONOTONIC;
-	else
-#endif
-	if (clock_getres(CLOCK_REALTIME, &res) == 0)
-		clocktouse = CLOCK_REALTIME;
-	else
-		return (-1);
-
-	/* Convert clock resolution to a double. */
-	*resd = res.tv_sec + res.tv_nsec * 0.000000001;
-
-	return (0);
-}
-
-static int
-getclocktime(struct timespec * ts)
-{
-
-	if (clock_gettime(clocktouse, ts))
-		return (-1);
-
-	return (0);
-}
-
-#else
-static int
-getclockres(double * resd)
-{
-
-	*resd = 1.0 / CLOCKS_PER_SEC;
-
-	return (0);
-}
-
-static int
-getclocktime(struct timespec * ts)
-{
-	struct timeval tv;
-
-	if (gettimeofday(&tv, NULL))
-		return (-1);
-	ts->tv_sec = tv.tv_sec;
-	ts->tv_nsec = tv.tv_usec * 1000;
-
-	return (0);
-}
-#endif
-
-static int
-getclockdiff(struct timespec * st, double * diffd)
-{
-	struct timespec en;
-
-	if (getclocktime(&en))
-		return (1);
-	*diffd = (en.tv_nsec - st->tv_nsec) * 0.000000001 +
-	    (en.tv_sec - st->tv_sec);
-
-	return (0);
-}
-
-/**
- * scryptenc_cpuperf(opps):
- * Estimate the number of salsa20/8 cores which can be executed per second,
- * and return the value via opps.
- */
-int
-scryptenc_cpuperf(double * opps)
-{
-	struct timespec st;
-	double resd, diffd;
-	uint64_t i = 0;
-
-	/* Get the clock resolution. */
-	if (getclockres(&resd))
-		return (2);
-
-#ifdef DEBUG
-	fprintf(stderr, "Clock resolution is %f\n", resd);
-#endif
-
-	/* Loop until the clock ticks. */
-	if (getclocktime(&st))
-		return (2);
-	do {
-		/* Do an scrypt. */
-		if (crypto_scrypt(NULL, 0, NULL, 0, 16, 1, 1, NULL, 0))
-			return (3);
-
-		/* Has the clock ticked? */
-		if (getclockdiff(&st, &diffd))
-			return (2);
-		if (diffd > 0)
-			break;
-	} while (1);
-
-	/* Count how many scrypts we can do before the next tick. */
-	if (getclocktime(&st))
-		return (2);
-	do {
-		/* Do an scrypt. */
-		if (crypto_scrypt(NULL, 0, NULL, 0, 128, 1, 1, NULL, 0))
-			return (3);
-
-		/* We invoked the salsa20/8 core 512 times. */
-		i += 512;
-
-		/* Check if we have looped for long enough. */
-		if (getclockdiff(&st, &diffd))
-			return (2);
-		if (diffd > resd)
-			break;
-	} while (1);
-
-#ifdef DEBUG
-	fprintf(stderr, "%ju salsa20/8 cores performed in %f seconds\n",
-	    (uintmax_t)i, diffd);
-#endif
-
-	/* We can do approximately i salsa20/8 cores per diffd seconds. */
-	*opps = i / diffd;
-	return (0);
-}
diff -pruN 0.8.0-0.3/scrypt-1.2.0/lib/scryptenc/scryptenc_cpuperf.h 0.8.20-1/scrypt-1.2.0/lib/scryptenc/scryptenc_cpuperf.h
--- 0.8.0-0.3/scrypt-1.2.0/lib/scryptenc/scryptenc_cpuperf.h	2015-08-08 18:45:05.000000000 +0000
+++ 0.8.20-1/scrypt-1.2.0/lib/scryptenc/scryptenc_cpuperf.h	1970-01-01 00:00:00.000000000 +0000
@@ -1,39 +0,0 @@
-/*-
- * Copyright 2009 Colin Percival
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * This file was originally written by Colin Percival as part of the Tarsnap
- * online backup system.
- */
-#ifndef _SCRYPTENC_CPUPERF_H_
-#define _SCRYPTENC_CPUPERF_H_
-
-/**
- * scryptenc_cpuperf(opps):
- * Estimate the number of salsa20/8 cores which can be executed per second,
- * and return the value via opps.
- */
-int scryptenc_cpuperf(double *);
-
-#endif /* !_SCRYPTENC_CPUPERF_H_ */
diff -pruN 0.8.0-0.3/scrypt-1.2.0/lib/scryptenc/scryptenc.h 0.8.20-1/scrypt-1.2.0/lib/scryptenc/scryptenc.h
--- 0.8.0-0.3/scrypt-1.2.0/lib/scryptenc/scryptenc.h	2015-08-08 18:45:05.000000000 +0000
+++ 0.8.20-1/scrypt-1.2.0/lib/scryptenc/scryptenc.h	1970-01-01 00:00:00.000000000 +0000
@@ -1,120 +0,0 @@
-/*-
- * Copyright 2009 Colin Percival
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * This file was originally written by Colin Percival as part of the Tarsnap
- * online backup system.
- */
-#ifndef _SCRYPTENC_H_
-#define _SCRYPTENC_H_
-
-#include <stdint.h>
-#include <stdio.h>
-
-/**
- * NOTE: This file provides prototypes for routines which encrypt/decrypt data
- * using a key derived from a password by using the scrypt key derivation
- * function.  If you are just trying to "hash" a password for user logins,
- * this is not the code you are looking for.  You want to use the crypt_scrypt
- * function directly.
- */
-
-/**
- * The parameters maxmem, maxmemfrac, and maxtime used by all of these
- * functions are defined as follows:
- * maxmem - maximum number of bytes of storage to use for V array (which is
- *     by far the largest consumer of memory).  If this value is set to 0, no
- *     maximum will be enforced; any other value less than 1 MiB will be
- *     treated as 1 MiB.
- * maxmemfrac - maximum fraction of available storage to use for the V array,
- *     where "available storage" is defined as the minimum out of the
- *     RLIMIT_AS, RLIMIT_DATA. and RLIMIT_RSS resource limits (if any are
- *     set).  If this value is set to 0 or more than 0.5 it will be treated
- *     as 0.5; and this value will never cause a limit of less than 1 MiB to
- *     be enforced.
- * maxtime - maximum amount of CPU time to spend computing the derived keys,
- *     in seconds.  This limit is only approximately enforced; the CPU
- *     performance is estimated and parameter limits are chosen accordingly.
- * For the encryption functions, the parameters to the scrypt key derivation
- * function are chosen to make the key as strong as possible subject to the
- * specified limits; for the decryption functions, the parameters used are
- * compared to the computed limits and an error is returned if decrypting
- * the data would take too much memory or CPU time.
- */
-/**
- * Return codes from scrypt(enc|dec)_(buf|file):
- * 0	success
- * 1	getrlimit or sysctl(hw.usermem) failed
- * 2	clock_getres or clock_gettime failed
- * 3	error computing derived key
- * 4	could not read salt from /dev/urandom
- * 5	error in OpenSSL
- * 6	malloc failed
- * 7	data is not a valid scrypt-encrypted block
- * 8	unrecognized scrypt format
- * 9	decrypting file would take too much memory
- * 10	decrypting file would take too long
- * 11	password is incorrect
- * 12	error writing output file
- * 13	error reading input file
- */
-
-/**
- * scryptenc_buf(inbuf, inbuflen, outbuf, passwd, passwdlen,
- *     maxmem, maxmemfrac, maxtime):
- * Encrypt inbuflen bytes from inbuf, writing the resulting inbuflen + 128
- * bytes to outbuf.
- */
-int scryptenc_buf(const uint8_t *, size_t, uint8_t *,
-    const uint8_t *, size_t, size_t, double, double);
-
-/**
- * scryptdec_buf(inbuf, inbuflen, outbuf, outlen, passwd, passwdlen,
- *     maxmem, maxmemfrac, maxtime):
- * Decrypt inbuflen bytes from inbuf, writing the result into outbuf and the
- * decrypted data length to outlen.  The allocated length of outbuf must
- * be at least inbuflen.
- */
-int scryptdec_buf(const uint8_t *, size_t, uint8_t *, size_t *,
-    const uint8_t *, size_t, size_t, double, double);
-
-/**
- * scryptenc_file(infile, outfile, passwd, passwdlen,
- *     maxmem, maxmemfrac, maxtime):
- * Read a stream from infile and encrypt it, writing the resulting stream to
- * outfile.
- */
-int scryptenc_file(FILE *, FILE *, const uint8_t *, size_t,
-    size_t, double, double);
-
-/**
- * scryptdec_file(infile, outfile, passwd, passwdlen,
- *     maxmem, maxmemfrac, maxtime):
- * Read a stream from infile and decrypt it, writing the resulting stream to
- * outfile.
- */
-int scryptdec_file(FILE *, FILE *, const uint8_t *, size_t,
-    size_t, double, double);
-
-#endif /* !_SCRYPTENC_H_ */
diff -pruN 0.8.0-0.3/scrypt-1.2.0/lib/util/memlimit.c 0.8.20-1/scrypt-1.2.0/lib/util/memlimit.c
--- 0.8.0-0.3/scrypt-1.2.0/lib/util/memlimit.c	2016-09-17 12:40:31.000000000 +0000
+++ 0.8.20-1/scrypt-1.2.0/lib/util/memlimit.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,356 +0,0 @@
-/*-
- * Copyright 2009 Colin Percival
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * This file was originally written by Colin Percival as part of the Tarsnap
- * online backup system.
- */
-#include "scrypt_platform.h"
-
-#include <sys/types.h>
-
-#ifndef _WIN32
-#include <sys/resource.h>
-#else
-#define _WIN32_WINNT 0x0502
-#include <Windows.h>
-#include <tchar.h>
-#endif
-
-#ifdef HAVE_SYS_PARAM_H
-#include <sys/param.h>
-#endif
-#ifdef HAVE_SYS_SYSCTL_H
-#include <sys/sysctl.h>
-#endif
-#ifdef HAVE_SYS_SYSINFO_H
-#include <sys/sysinfo.h>
-#endif
-
-#include <errno.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <string.h>
-#include <unistd.h>
-
-#ifdef DEBUG
-#include <stdio.h>
-#endif
-
-#include "memlimit.h"
-
-/* If we don't have CTL_HW, we can't use HW_USERMEM. */
-#ifndef CTL_HW
-#undef HW_USERMEM
-#endif
-
-#ifdef CTL_HW
-static int
-memlimit_sysctl_hw(size_t * memlimit, int mibleaf)
-{
-	int mib[2];
-	uint8_t sysctlbuf[8];
-	size_t sysctlbuflen = 8;
-	uint64_t sysctlval;
-
-	/* Ask the kernel how much RAM we have. */
-	mib[0] = CTL_HW;
-	mib[1] = mibleaf;
-	if (sysctl(mib, 2, sysctlbuf, &sysctlbuflen, NULL, 0))
-		return (1);
-
-	/*
-	 * If we read 8 bytes out, assume this is a system-endian uint64_t.
-	 * If we only read 4 bytes out, the OS is trying to give us a
-	 * uint32_t answer -- but given how many systems now have 4GB+ of RAM,
-	 * it's probably truncating, and we really can't trust the value we
-	 * have returned to us.
-	 */
-	if (sysctlbuflen == sizeof(uint64_t))
-		memcpy(&sysctlval, sysctlbuf, sizeof(uint64_t));
-	else if (sysctlbuflen == sizeof(uint32_t))
-		sysctlval = SIZE_MAX;
-	else
-		return (1);
-
-	/* Return the sysctl value, but clamp to SIZE_MAX if necessary. */
-#if UINT64_MAX > SIZE_MAX
-	if (sysctlval > SIZE_MAX)
-		*memlimit = SIZE_MAX;
-	else
-		*memlimit = sysctlval;
-#else
-	*memlimit = sysctlval;
-#endif
-
-	/* Success! */
-	return (0);
-}
-#endif
-
-/* If we don't HAVE_STRUCT_SYSINFO, we can't use sysinfo. */
-#ifndef HAVE_STRUCT_SYSINFO
-#undef HAVE_SYSINFO
-#endif
-
-/* If we don't HAVE_STRUCT_SYSINFO_TOTALRAM, we can't use sysinfo. */
-#ifndef HAVE_STRUCT_SYSINFO_TOTALRAM
-#undef HAVE_SYSINFO
-#endif
-
-#ifdef HAVE_SYSINFO
-static int
-memlimit_sysinfo(size_t * memlimit)
-{
-	struct sysinfo info;
-	uint64_t totalmem;
-
-	/* Get information from the kernel. */
-	if (sysinfo(&info))
-		return (1);
-	totalmem = info.totalram;
-
-	/* If we're on a modern kernel, adjust based on mem_unit. */
-#ifdef HAVE_STRUCT_SYSINFO_MEM_UNIT
-	totalmem = totalmem * info.mem_unit;
-#endif
-
-	/* Return the value, but clamp to SIZE_MAX if necessary. */
-#if UINT64_MAX > SIZE_MAX
-	if (totalmem > SIZE_MAX)
-		*memlimit = SIZE_MAX;
-	else
-		*memlimit = totalmem;
-#else
-	*memlimit = totalmem;
-#endif
-
-	/* Success! */
-	return (0);
-}
-#endif /* HAVE_SYSINFO */
-
-#ifndef _WIN32
-static int
-memlimit_rlimit(size_t * memlimit)
-{
-	struct rlimit rl;
-	uint64_t memrlimit;
-
-	/* Find the least of... */
-	memrlimit = (uint64_t)(-1);
-
-	/* ... RLIMIT_AS... */
-#ifdef RLIMIT_AS
-	if (getrlimit(RLIMIT_AS, &rl))
-		return (1);
-	if ((rl.rlim_cur != RLIM_INFINITY) &&
-		((uint64_t)rl.rlim_cur < memrlimit))
-		memrlimit = rl.rlim_cur;
-#endif
-
-	/* ... RLIMIT_DATA... */
-	if (getrlimit(RLIMIT_DATA, &rl))
-		return (1);
-	if ((rl.rlim_cur != RLIM_INFINITY) &&
-		((uint64_t)rl.rlim_cur < memrlimit))
-		memrlimit = rl.rlim_cur;
-
-	/* ... and RLIMIT_RSS. */
-#ifdef RLIMIT_RSS
-	if (getrlimit(RLIMIT_RSS, &rl))
-		return (1);
-	if ((rl.rlim_cur != RLIM_INFINITY) &&
-		((uint64_t)rl.rlim_cur < memrlimit))
-		memrlimit = rl.rlim_cur;
-#endif
-
-	/* Return the value, but clamp to SIZE_MAX if necessary. */
-#if UINT64_MAX > SIZE_MAX
-	if (memrlimit > SIZE_MAX)
-		*memlimit = SIZE_MAX;
-	else
-		*memlimit = memrlimit;
-#else
-	*memlimit = memrlimit;
-#endif
-
-	/* Success! */
-	return (0);
-}
-#endif
-
-#ifdef _SC_PHYS_PAGES
-
-/* Some systems define _SC_PAGESIZE instead of _SC_PAGE_SIZE. */
-#ifndef _SC_PAGE_SIZE
-#define _SC_PAGE_SIZE _SC_PAGESIZE
-#endif
-
-static int
-memlimit_sysconf(size_t * memlimit)
-{
-	long pagesize;
-	long physpages;
-	uint64_t totalmem;
-
-	/* Set errno to 0 in order to distinguish "no limit" from "error". */
-	errno = 0;
-
-	/* Read the two limits. */
-	if (((pagesize = sysconf(_SC_PAGE_SIZE)) == -1) ||
-		((physpages = sysconf(_SC_PHYS_PAGES)) == -1)) {
-		/* Did an error occur? */
-		if (errno != 0)
-			return (1);
-
-		/* If not, there is no limit. */
-		totalmem = (uint64_t)(-1);
-	} else {
-		/* Compute the limit. */
-		totalmem = (uint64_t)(pagesize) * (uint64_t)(physpages);
-	}
-
-	/* Return the value, but clamp to SIZE_MAX if necessary. */
-#if UINT64_MAX > SIZE_MAX
-	if (totalmem > SIZE_MAX)
-		*memlimit = SIZE_MAX;
-	else
-		*memlimit = totalmem;
-#else
-	*memlimit = totalmem;
-#endif
-
-	/* Success! */
-	return (0);
-}
-#endif
-
-#ifdef _WIN32
-static int
-memlimit_windows(size_t * memlimit)
-{
-	MEMORYSTATUSEX state;
-	state.dwLength = sizeof(state);
-
-	if(!GlobalMemoryStatusEx (&state))
-		return (1);
-
-
-	*memlimit = state.ullTotalPhys;
-	return (0);
-
-}
-#endif
-
-int
-memtouse(size_t maxmem, double maxmemfrac, size_t * memlimit)
-{
-	size_t usermem_memlimit, memsize_memlimit;
-	size_t sysinfo_memlimit, rlimit_memlimit;
-	size_t sysconf_memlimit, windows_memlimit;
-	size_t memlimit_min;
-	size_t memavail;
-
-	/* Get memory limits. */
-#ifdef HW_USERMEM
-	if (memlimit_sysctl_hw(&usermem_memlimit, HW_USERMEM))
-		return (1);
-#else
-	usermem_memlimit = SIZE_MAX;
-#endif
-#ifdef HW_MEMSIZE
-	if (memlimit_sysctl_hw(&memsize_memlimit, HW_MEMSIZE))
-		return (1);
-#else
-	memsize_memlimit = SIZE_MAX;
-#endif
-#ifdef HAVE_SYSINFO
-	if (memlimit_sysinfo(&sysinfo_memlimit))
-		return (1);
-#else
-	sysinfo_memlimit = SIZE_MAX;
-#endif
-#ifndef _WIN32
-	if (memlimit_rlimit(&rlimit_memlimit))
-		return (1);
-#else
-	rlimit_memlimit = SIZE_MAX;
-#endif
-#ifdef _SC_PHYS_PAGES
-	if (memlimit_sysconf(&sysconf_memlimit))
-		return (1);
-#else
-	sysconf_memlimit = SIZE_MAX;
-#endif
-#ifdef _WIN32
-	if (memlimit_windows(&windows_memlimit))
-		return (1);
-#else
-	windows_memlimit = SIZE_MAX;
-#endif
-
-#ifdef DEBUG
-	fprintf(stderr, "Memory limits are %zu %zu %zu %zu %zu\n",
-		usermem_memlimit, memsize_memlimit,
-		sysinfo_memlimit, rlimit_memlimit,
-		sysconf_memlimit);
-#endif
-
-	/* Find the smallest of them. */
-	memlimit_min = SIZE_MAX;
-	if (memlimit_min > usermem_memlimit)
-		memlimit_min = usermem_memlimit;
-	if (memlimit_min > memsize_memlimit)
-		memlimit_min = memsize_memlimit;
-	if (memlimit_min > sysinfo_memlimit)
-		memlimit_min = sysinfo_memlimit;
-	if (memlimit_min > rlimit_memlimit)
-		memlimit_min = rlimit_memlimit;
-	if (memlimit_min > sysconf_memlimit)
-		memlimit_min = sysconf_memlimit;
-	if (memlimit_min > windows_memlimit)
-		memlimit_min = windows_memlimit;
-
-	/* Only use the specified fraction of the available memory. */
-	if ((maxmemfrac > 0.5) || (maxmemfrac == 0.0))
-		maxmemfrac = 0.5;
-	memavail = maxmemfrac * memlimit_min;
-
-	/* Don't use more than the specified maximum. */
-	if ((maxmem > 0) && (memavail > maxmem))
-		memavail = maxmem;
-
-	/* But always allow at least 1 MiB. */
-	if (memavail < 1048576)
-		memavail = 1048576;
-
-#ifdef DEBUG
-	fprintf(stderr, "Allowing up to %zu memory to be used\n", memavail);
-#endif
-
-	/* Return limit via the provided pointer. */
-	*memlimit = memavail;
-	return (0);
-}
diff -pruN 0.8.0-0.3/scrypt-1.2.0/lib/util/memlimit.h 0.8.20-1/scrypt-1.2.0/lib/util/memlimit.h
--- 0.8.0-0.3/scrypt-1.2.0/lib/util/memlimit.h	2015-08-08 18:45:05.000000000 +0000
+++ 0.8.20-1/scrypt-1.2.0/lib/util/memlimit.h	1970-01-01 00:00:00.000000000 +0000
@@ -1,42 +0,0 @@
-/*-
- * Copyright 2009 Colin Percival
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * This file was originally written by Colin Percival as part of the Tarsnap
- * online backup system.
- */
-#ifndef _MEMLIMIT_H_
-#define _MEMLIMIT_H_
-
-#include <stddef.h>
-
-/**
- * memtouse(maxmem, maxmemfrac, memlimit):
- * Examine the system and return via memlimit the amount of RAM which should
- * be used -- the specified fraction of the available RAM, but no more than
- * maxmem, and no less than 1MiB.
- */
-int memtouse(size_t, double, size_t *);
-
-#endif /* !_MEMLIMIT_H_ */
diff -pruN 0.8.0-0.3/scrypt-1.2.0/libcperciva/alg/sha256.c 0.8.20-1/scrypt-1.2.0/libcperciva/alg/sha256.c
--- 0.8.0-0.3/scrypt-1.2.0/libcperciva/alg/sha256.c	2015-08-08 18:45:05.000000000 +0000
+++ 0.8.20-1/scrypt-1.2.0/libcperciva/alg/sha256.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,442 +0,0 @@
-#include <assert.h>
-#include <stdint.h>
-#include <string.h>
-
-#include "insecure_memzero.h"
-#include "sysendian.h"
-
-#include "sha256.h"
-
-/*
- * Encode a length len/4 vector of (uint32_t) into a length len vector of
- * (uint8_t) in big-endian form.  Assumes len is a multiple of 4.
- */
-static void
-be32enc_vect(uint8_t * dst, const uint32_t * src, size_t len)
-{
-	size_t i;
-
-	/* Sanity-check. */
-	assert(len % 4 == 0);
-
-	/* Encode vector, one word at a time. */
-	for (i = 0; i < len / 4; i++)
-		be32enc(dst + i * 4, src[i]);
-}
-
-/*
- * Decode a big-endian length len vector of (uint8_t) into a length
- * len/4 vector of (uint32_t).  Assumes len is a multiple of 4.
- */
-static void
-be32dec_vect(uint32_t * dst, const uint8_t * src, size_t len)
-{
-	size_t i;
-
-	/* Sanity-check. */
-	assert(len % 4 == 0);
-
-	/* Decode vector, one word at a time. */
-	for (i = 0; i < len / 4; i++)
-		dst[i] = be32dec(src + i * 4);
-}
-
-/* Elementary functions used by SHA256 */
-#define Ch(x, y, z)	((x & (y ^ z)) ^ z)
-#define Maj(x, y, z)	((x & (y | z)) | (y & z))
-#define SHR(x, n)	(x >> n)
-#define ROTR(x, n)	((x >> n) | (x << (32 - n)))
-#define S0(x)		(ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22))
-#define S1(x)		(ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25))
-#define s0(x)		(ROTR(x, 7) ^ ROTR(x, 18) ^ SHR(x, 3))
-#define s1(x)		(ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10))
-
-/* SHA256 round function */
-#define RND(a, b, c, d, e, f, g, h, k)			\
-	t0 = h + S1(e) + Ch(e, f, g) + k;		\
-	t1 = S0(a) + Maj(a, b, c);			\
-	d += t0;					\
-	h  = t0 + t1;
-
-/* Adjusted round function for rotating state */
-#define RNDr(S, W, i, k)			\
-	RND(S[(64 - i) % 8], S[(65 - i) % 8],	\
-	    S[(66 - i) % 8], S[(67 - i) % 8],	\
-	    S[(68 - i) % 8], S[(69 - i) % 8],	\
-	    S[(70 - i) % 8], S[(71 - i) % 8],	\
-	    W[i] + k)
-
-/*
- * SHA256 block compression function.  The 256-bit state is transformed via
- * the 512-bit input block to produce a new state.
- */
-static void
-SHA256_Transform(uint32_t * state, const uint8_t block[64])
-{
-	uint32_t W[64];
-	uint32_t S[8];
-	uint32_t t0, t1;
-	int i;
-
-	/* 1. Prepare message schedule W. */
-	be32dec_vect(W, block, 64);
-	for (i = 16; i < 64; i++)
-		W[i] = s1(W[i - 2]) + W[i - 7] + s0(W[i - 15]) + W[i - 16];
-
-	/* 2. Initialize working variables. */
-	memcpy(S, state, 32);
-
-	/* 3. Mix. */
-	RNDr(S, W, 0, 0x428a2f98);
-	RNDr(S, W, 1, 0x71374491);
-	RNDr(S, W, 2, 0xb5c0fbcf);
-	RNDr(S, W, 3, 0xe9b5dba5);
-	RNDr(S, W, 4, 0x3956c25b);
-	RNDr(S, W, 5, 0x59f111f1);
-	RNDr(S, W, 6, 0x923f82a4);
-	RNDr(S, W, 7, 0xab1c5ed5);
-	RNDr(S, W, 8, 0xd807aa98);
-	RNDr(S, W, 9, 0x12835b01);
-	RNDr(S, W, 10, 0x243185be);
-	RNDr(S, W, 11, 0x550c7dc3);
-	RNDr(S, W, 12, 0x72be5d74);
-	RNDr(S, W, 13, 0x80deb1fe);
-	RNDr(S, W, 14, 0x9bdc06a7);
-	RNDr(S, W, 15, 0xc19bf174);
-	RNDr(S, W, 16, 0xe49b69c1);
-	RNDr(S, W, 17, 0xefbe4786);
-	RNDr(S, W, 18, 0x0fc19dc6);
-	RNDr(S, W, 19, 0x240ca1cc);
-	RNDr(S, W, 20, 0x2de92c6f);
-	RNDr(S, W, 21, 0x4a7484aa);
-	RNDr(S, W, 22, 0x5cb0a9dc);
-	RNDr(S, W, 23, 0x76f988da);
-	RNDr(S, W, 24, 0x983e5152);
-	RNDr(S, W, 25, 0xa831c66d);
-	RNDr(S, W, 26, 0xb00327c8);
-	RNDr(S, W, 27, 0xbf597fc7);
-	RNDr(S, W, 28, 0xc6e00bf3);
-	RNDr(S, W, 29, 0xd5a79147);
-	RNDr(S, W, 30, 0x06ca6351);
-	RNDr(S, W, 31, 0x14292967);
-	RNDr(S, W, 32, 0x27b70a85);
-	RNDr(S, W, 33, 0x2e1b2138);
-	RNDr(S, W, 34, 0x4d2c6dfc);
-	RNDr(S, W, 35, 0x53380d13);
-	RNDr(S, W, 36, 0x650a7354);
-	RNDr(S, W, 37, 0x766a0abb);
-	RNDr(S, W, 38, 0x81c2c92e);
-	RNDr(S, W, 39, 0x92722c85);
-	RNDr(S, W, 40, 0xa2bfe8a1);
-	RNDr(S, W, 41, 0xa81a664b);
-	RNDr(S, W, 42, 0xc24b8b70);
-	RNDr(S, W, 43, 0xc76c51a3);
-	RNDr(S, W, 44, 0xd192e819);
-	RNDr(S, W, 45, 0xd6990624);
-	RNDr(S, W, 46, 0xf40e3585);
-	RNDr(S, W, 47, 0x106aa070);
-	RNDr(S, W, 48, 0x19a4c116);
-	RNDr(S, W, 49, 0x1e376c08);
-	RNDr(S, W, 50, 0x2748774c);
-	RNDr(S, W, 51, 0x34b0bcb5);
-	RNDr(S, W, 52, 0x391c0cb3);
-	RNDr(S, W, 53, 0x4ed8aa4a);
-	RNDr(S, W, 54, 0x5b9cca4f);
-	RNDr(S, W, 55, 0x682e6ff3);
-	RNDr(S, W, 56, 0x748f82ee);
-	RNDr(S, W, 57, 0x78a5636f);
-	RNDr(S, W, 58, 0x84c87814);
-	RNDr(S, W, 59, 0x8cc70208);
-	RNDr(S, W, 60, 0x90befffa);
-	RNDr(S, W, 61, 0xa4506ceb);
-	RNDr(S, W, 62, 0xbef9a3f7);
-	RNDr(S, W, 63, 0xc67178f2);
-
-	/* 4. Mix local working variables into global state. */
-	for (i = 0; i < 8; i++)
-		state[i] += S[i];
-
-	/* Clean the stack. */
-	insecure_memzero(W, 256);
-	insecure_memzero(S, 32);
-	insecure_memzero(&t0, sizeof(uint32_t));
-	insecure_memzero(&t1, sizeof(uint32_t));
-}
-
-static uint8_t PAD[64] = {
-	0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-};
-
-/* Add padding and terminating bit-count. */
-static void
-SHA256_Pad(SHA256_CTX * ctx)
-{
-	uint8_t len[8];
-	uint32_t r, plen;
-
-	/*
-	 * Convert length to a vector of bytes -- we do this now rather
-	 * than later because the length will change after we pad.
-	 */
-	be64enc(len, ctx->count);
-
-	/* Add 1--64 bytes so that the resulting length is 56 mod 64. */
-	r = (ctx->count >> 3) & 0x3f;
-	plen = (r < 56) ? (56 - r) : (120 - r);
-	SHA256_Update(ctx, PAD, (size_t)plen);
-
-	/* Add the terminating bit-count. */
-	SHA256_Update(ctx, len, 8);
-}
-
-/* Magic initialization constants. */
-static const uint32_t initstate[8] = {
-	0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A,
-	0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19
-};
-
-/**
- * SHA256_Init(ctx):
- * Initialize the SHA256 context ${ctx}.
- */
-void
-SHA256_Init(SHA256_CTX * ctx)
-{
-
-	/* Zero bits processed so far. */
-	ctx->count = 0;
-
-	/* Initialize state. */
-	memcpy(ctx->state, initstate, sizeof(initstate));
-}
-
-/**
- * SHA256_Update(ctx, in, len):
- * Input ${len} bytes from ${in} into the SHA256 context ${ctx}.
- */
-void
-SHA256_Update(SHA256_CTX * ctx, const void * in, size_t len)
-{
-	uint32_t r;
-	const uint8_t * src = in;
-
-	/* Return immediately if we have nothing to do. */
-	if (len == 0)
-		return;
-
-	/* Number of bytes left in the buffer from previous updates. */
-	r = (ctx->count >> 3) & 0x3f;
-
-	/* Update number of bits. */
-	ctx->count += (uint64_t)(len) << 3;
-
-	/* Handle the case where we don't need to perform any transforms. */
-	if (len < 64 - r) {
-		memcpy(&ctx->buf[r], src, len);
-		return;
-	}
-
-	/* Finish the current block. */
-	memcpy(&ctx->buf[r], src, 64 - r);
-	SHA256_Transform(ctx->state, ctx->buf);
-	src += 64 - r;
-	len -= 64 - r;
-
-	/* Perform complete blocks. */
-	while (len >= 64) {
-		SHA256_Transform(ctx->state, src);
-		src += 64;
-		len -= 64;
-	}
-
-	/* Copy left over data into buffer. */
-	memcpy(ctx->buf, src, len);
-}
-
-/**
- * SHA256_Final(digest, ctx):
- * Output the SHA256 hash of the data input to the context ${ctx} into the
- * buffer ${digest}.
- */
-void
-SHA256_Final(uint8_t digest[32], SHA256_CTX * ctx)
-{
-
-	/* Add padding. */
-	SHA256_Pad(ctx);
-
-	/* Write the hash. */
-	be32enc_vect(digest, ctx->state, 32);
-
-	/* Clear the context state. */
-	insecure_memzero(ctx, sizeof(SHA256_CTX));
-}
-
-/**
- * SHA256_Buf(in, len, digest):
- * Compute the SHA256 hash of ${len} bytes from $in} and write it to ${digest}.
- */
-void
-SHA256_Buf(const void * in, size_t len, uint8_t digest[32])
-{
-	SHA256_CTX ctx;
-
-	SHA256_Init(&ctx);
-	SHA256_Update(&ctx, in, len);
-	SHA256_Final(digest, &ctx);
-}
-
-/**
- * HMAC_SHA256_Init(ctx, K, Klen):
- * Initialize the HMAC-SHA256 context ${ctx} with ${Klen} bytes of key from
- * ${K}.
- */
-void
-HMAC_SHA256_Init(HMAC_SHA256_CTX * ctx, const void * _K, size_t Klen)
-{
-	uint8_t pad[64];
-	uint8_t khash[32];
-	const uint8_t * K = _K;
-	size_t i;
-
-	/* If Klen > 64, the key is really SHA256(K). */
-	if (Klen > 64) {
-		SHA256_Init(&ctx->ictx);
-		SHA256_Update(&ctx->ictx, K, Klen);
-		SHA256_Final(khash, &ctx->ictx);
-		K = khash;
-		Klen = 32;
-	}
-
-	/* Inner SHA256 operation is SHA256(K xor [block of 0x36] || data). */
-	SHA256_Init(&ctx->ictx);
-	memset(pad, 0x36, 64);
-	for (i = 0; i < Klen; i++)
-		pad[i] ^= K[i];
-	SHA256_Update(&ctx->ictx, pad, 64);
-
-	/* Outer SHA256 operation is SHA256(K xor [block of 0x5c] || hash). */
-	SHA256_Init(&ctx->octx);
-	memset(pad, 0x5c, 64);
-	for (i = 0; i < Klen; i++)
-		pad[i] ^= K[i];
-	SHA256_Update(&ctx->octx, pad, 64);
-
-	/* Clean the stack. */
-	insecure_memzero(khash, 32);
-	insecure_memzero(pad, 64);
-}
-
-/**
- * HMAC_SHA256_Update(ctx, in, len):
- * Input ${len} bytes from ${in} into the HMAC-SHA256 context ${ctx}.
- */
-void
-HMAC_SHA256_Update(HMAC_SHA256_CTX * ctx, const void * in, size_t len)
-{
-
-	/* Feed data to the inner SHA256 operation. */
-	SHA256_Update(&ctx->ictx, in, len);
-}
-
-/**
- * HMAC_SHA256_Final(digest, ctx):
- * Output the HMAC-SHA256 of the data input to the context ${ctx} into the
- * buffer ${digest}.
- */
-void
-HMAC_SHA256_Final(uint8_t digest[32], HMAC_SHA256_CTX * ctx)
-{
-	uint8_t ihash[32];
-
-	/* Finish the inner SHA256 operation. */
-	SHA256_Final(ihash, &ctx->ictx);
-
-	/* Feed the inner hash to the outer SHA256 operation. */
-	SHA256_Update(&ctx->octx, ihash, 32);
-
-	/* Finish the outer SHA256 operation. */
-	SHA256_Final(digest, &ctx->octx);
-
-	/* Clean the stack. */
-	insecure_memzero(ihash, 32);
-}
-
-/**
- * HMAC_SHA256_Buf(K, Klen, in, len, digest):
- * Compute the HMAC-SHA256 of ${len} bytes from ${in} using the key ${K} of
- * length ${Klen}, and write the result to ${digest}.
- */
-void
-HMAC_SHA256_Buf(const void * K, size_t Klen, const void * in, size_t len,
-    uint8_t digest[32])
-{
-	HMAC_SHA256_CTX ctx;
-
-	HMAC_SHA256_Init(&ctx, K, Klen);
-	HMAC_SHA256_Update(&ctx, in, len);
-	HMAC_SHA256_Final(digest, &ctx);
-}
-
-/**
- * PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, c, buf, dkLen):
- * Compute PBKDF2(passwd, salt, c, dkLen) using HMAC-SHA256 as the PRF, and
- * write the output to buf.  The value dkLen must be at most 32 * (2^32 - 1).
- */
-void
-PBKDF2_SHA256(const uint8_t * passwd, size_t passwdlen, const uint8_t * salt,
-    size_t saltlen, uint64_t c, uint8_t * buf, size_t dkLen)
-{
-	HMAC_SHA256_CTX PShctx, hctx;
-	size_t i;
-	uint8_t ivec[4];
-	uint8_t U[32];
-	uint8_t T[32];
-	uint64_t j;
-	int k;
-	size_t clen;
-
-	/* Sanity-check. */
-	assert(dkLen <= 32 * (size_t)(UINT32_MAX));
-
-	/* Compute HMAC state after processing P and S. */
-	HMAC_SHA256_Init(&PShctx, passwd, passwdlen);
-	HMAC_SHA256_Update(&PShctx, salt, saltlen);
-
-	/* Iterate through the blocks. */
-	for (i = 0; i * 32 < dkLen; i++) {
-		/* Generate INT(i + 1). */
-		be32enc(ivec, (uint32_t)(i + 1));
-
-		/* Compute U_1 = PRF(P, S || INT(i)). */
-		memcpy(&hctx, &PShctx, sizeof(HMAC_SHA256_CTX));
-		HMAC_SHA256_Update(&hctx, ivec, 4);
-		HMAC_SHA256_Final(U, &hctx);
-
-		/* T_i = U_1 ... */
-		memcpy(T, U, 32);
-
-		for (j = 2; j <= c; j++) {
-			/* Compute U_j. */
-			HMAC_SHA256_Init(&hctx, passwd, passwdlen);
-			HMAC_SHA256_Update(&hctx, U, 32);
-			HMAC_SHA256_Final(U, &hctx);
-
-			/* ... xor U_j ... */
-			for (k = 0; k < 32; k++)
-				T[k] ^= U[k];
-		}
-
-		/* Copy as many bytes as necessary into buf. */
-		clen = dkLen - i * 32;
-		if (clen > 32)
-			clen = 32;
-		memcpy(&buf[i * 32], T, clen);
-	}
-
-	/* Clean PShctx, since we never called _Final on it. */
-	insecure_memzero(&PShctx, sizeof(HMAC_SHA256_CTX));
-}
diff -pruN 0.8.0-0.3/scrypt-1.2.0/libcperciva/alg/sha256.h 0.8.20-1/scrypt-1.2.0/libcperciva/alg/sha256.h
--- 0.8.0-0.3/scrypt-1.2.0/libcperciva/alg/sha256.h	2015-08-08 18:45:05.000000000 +0000
+++ 0.8.20-1/scrypt-1.2.0/libcperciva/alg/sha256.h	1970-01-01 00:00:00.000000000 +0000
@@ -1,95 +0,0 @@
-#ifndef _SHA256_H_
-#define _SHA256_H_
-
-#include <stddef.h>
-#include <stdint.h>
-
-/*
- * Use #defines in order to avoid namespace collisions with anyone else's
- * SHA256 code (e.g., the code in OpenSSL).
- */
-#define SHA256_Init libcperciva_SHA256_Init
-#define SHA256_Update libcperciva_SHA256_Update
-#define SHA256_Final libcperciva_SHA256_Final
-#define SHA256_Buf libcperciva_SHA256_Buf
-#define SHA256_CTX libcperciva_SHA256_CTX
-#define HMAC_SHA256_Init libcperciva_HMAC_SHA256_Init
-#define HMAC_SHA256_Update libcperciva_HMAC_SHA256_Update
-#define HMAC_SHA256_Final libcperciva_HMAC_SHA256_Final
-#define HMAC_SHA256_Buf libcperciva_HMAC_SHA256_Buf
-#define HMAC_SHA256_CTX libcperciva_HMAC_SHA256_CTX
-
-/* Context structure for SHA256 operations. */
-typedef struct {
-	uint32_t state[8];
-	uint64_t count;
-	uint8_t buf[64];
-} SHA256_CTX;
-
-/**
- * SHA256_Init(ctx):
- * Initialize the SHA256 context ${ctx}.
- */
-void SHA256_Init(SHA256_CTX *);
-
-/**
- * SHA256_Update(ctx, in, len):
- * Input ${len} bytes from ${in} into the SHA256 context ${ctx}.
- */
-void SHA256_Update(SHA256_CTX *, const void *, size_t);
-
-/**
- * SHA256_Final(digest, ctx):
- * Output the SHA256 hash of the data input to the context ${ctx} into the
- * buffer ${digest}.
- */
-void SHA256_Final(uint8_t[32], SHA256_CTX *);
-
-/**
- * SHA256_Buf(in, len, digest):
- * Compute the SHA256 hash of ${len} bytes from $in} and write it to ${digest}.
- */
-void SHA256_Buf(const void *, size_t, uint8_t[32]);
-
-/* Context structure for HMAC-SHA256 operations. */
-typedef struct {
-	SHA256_CTX ictx;
-	SHA256_CTX octx;
-} HMAC_SHA256_CTX;
-
-/**
- * HMAC_SHA256_Init(ctx, K, Klen):
- * Initialize the HMAC-SHA256 context ${ctx} with ${Klen} bytes of key from
- * ${K}.
- */
-void HMAC_SHA256_Init(HMAC_SHA256_CTX *, const void *, size_t);
-
-/**
- * HMAC_SHA256_Update(ctx, in, len):
- * Input ${len} bytes from ${in} into the HMAC-SHA256 context ${ctx}.
- */
-void HMAC_SHA256_Update(HMAC_SHA256_CTX *, const void *, size_t);
-
-/**
- * HMAC_SHA256_Final(digest, ctx):
- * Output the HMAC-SHA256 of the data input to the context ${ctx} into the
- * buffer ${digest}.
- */
-void HMAC_SHA256_Final(uint8_t[32], HMAC_SHA256_CTX *);
-
-/**
- * HMAC_SHA256_Buf(K, Klen, in, len, digest):
- * Compute the HMAC-SHA256 of ${len} bytes from ${in} using the key ${K} of
- * length ${Klen}, and write the result to ${digest}.
- */
-void HMAC_SHA256_Buf(const void *, size_t, const void *, size_t, uint8_t[32]);
-
-/**
- * PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, c, buf, dkLen):
- * Compute PBKDF2(passwd, salt, c, dkLen) using HMAC-SHA256 as the PRF, and
- * write the output to buf.  The value dkLen must be at most 32 * (2^32 - 1).
- */
-void PBKDF2_SHA256(const uint8_t *, size_t, const uint8_t *, size_t,
-    uint64_t, uint8_t *, size_t);
-
-#endif /* !_SHA256_H_ */
diff -pruN 0.8.0-0.3/scrypt-1.2.0/libcperciva/cpusupport/cpusupport.h 0.8.20-1/scrypt-1.2.0/libcperciva/cpusupport/cpusupport.h
--- 0.8.0-0.3/scrypt-1.2.0/libcperciva/cpusupport/cpusupport.h	2015-08-08 18:45:05.000000000 +0000
+++ 0.8.20-1/scrypt-1.2.0/libcperciva/cpusupport/cpusupport.h	1970-01-01 00:00:00.000000000 +0000
@@ -1,64 +0,0 @@
-#ifndef _CPUSUPPORT_H_
-#define _CPUSUPPORT_H_
-
-/*
- * To enable support for non-portable CPU features at compile time, one or
- * more CPUSUPPORT_ARCH_FEATURE macros should be defined.  This can be done
- * directly on the compiler command line; or a file can be created with the
- * necessary #define lines and then -D CPUSUPPORT_CONFIG_FILE=cpuconfig.h
- * (or similar) can be provided to include that file here.
- */
-#ifdef CPUSUPPORT_CONFIG_FILE
-#include CPUSUPPORT_CONFIG_FILE
-#endif
-
-/*
- * The CPUSUPPORT_FEATURE macro declares the necessary variables and
- * functions for detecting CPU feature support at run time.  The function
- * defined in the macro acts to cache the result of the ..._detect function
- * using the ..._present and ..._init variables.
- */
-#define CPUSUPPORT_FEATURE(arch, feature)				\
-	extern int cpusupport_ ## arch ## _ ## feature ## _present;	\
-	extern int cpusupport_ ## arch ## _ ## feature ## _init;	\
-	int cpusupport_ ## arch ## _ ## feature ## _detect(void);	\
-									\
-	static inline int						\
-	cpusupport_ ## arch ## _ ## feature(void)			\
-	{								\
-									\
-		if (cpusupport_ ## arch ## _ ## feature ## _present)	\
-			return (1);					\
-		else if (cpusupport_ ## arch ## _ ## feature ## _init)	\
-			return (0);					\
-		cpusupport_ ## arch ## _ ## feature ## _present = 	\
-		    cpusupport_ ## arch ##_ ## feature ## _detect();	\
-		cpusupport_ ## arch ## _ ## feature ## _init = 1;	\
-		return (cpusupport_ ## arch ## _ ## feature ## _present); \
-	}								\
-	struct cpusupport_ ## arch ## _ ## feature ## _dummy
-
-/*
- * CPUSUPPORT_FEATURE_DECL(arch, feature):
- * Macro which defines variables and provides a function declaration for
- * detecting the presence of "feature" on the "arch" architecture.  The
- * function body following this macro expansion must return nonzero if the
- * feature is present, or zero if the feature is not present or the detection
- * fails for any reason.
- */
-#define CPUSUPPORT_FEATURE_DECL(arch, feature)				\
-	int cpusupport_ ## arch ## _ ## feature ## _present = 0;	\
-	int cpusupport_ ## arch ## _ ## feature ## _init = 0;		\
-	int								\
-	cpusupport_ ## arch ## _ ## feature ## _detect(void)
-
-/*
- * Any features listed here must have associated C files compiled and linked
- * in, since the macro references symbols which must be defined.  Projects
- * which do not need to detect certain CPU features may wish to remove lines
- * from this list so that the associated C files can be omitted.
- */
-CPUSUPPORT_FEATURE(x86, aesni);
-CPUSUPPORT_FEATURE(x86, sse2);
-
-#endif /* !_CPUSUPPORT_H_ */
diff -pruN 0.8.0-0.3/scrypt-1.2.0/libcperciva/crypto/crypto_aes_aesni.c 0.8.20-1/scrypt-1.2.0/libcperciva/crypto/crypto_aes_aesni.c
--- 0.8.0-0.3/scrypt-1.2.0/libcperciva/crypto/crypto_aes_aesni.c	2015-08-08 18:45:05.000000000 +0000
+++ 0.8.20-1/scrypt-1.2.0/libcperciva/crypto/crypto_aes_aesni.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,236 +0,0 @@
-#include "cpusupport.h"
-#ifdef CPUSUPPORT_X86_AESNI
-
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-#include <wmmintrin.h>
-
-#include "insecure_memzero.h"
-#include "warnp.h"
-
-#include "crypto_aes_aesni.h"
-
-/* Expanded-key structure. */
-struct crypto_aes_key_aesni {
-	uint8_t rkeys_buf[15 * sizeof(__m128i) + (sizeof(__m128i) - 1)];
-	__m128i * rkeys;
-	size_t nr;
-};
-
-/* Compute an AES-128 round key. */
-#define MKRKEY128(rkeys, i, rcon) do {				\
-	__m128i _s = rkeys[i - 1];				\
-	__m128i _t = rkeys[i - 1];				\
-	_s = _mm_xor_si128(_s, _mm_slli_si128(_s, 4));		\
-	_s = _mm_xor_si128(_s, _mm_slli_si128(_s, 8));		\
-	_t = _mm_aeskeygenassist_si128(_t, rcon);		\
-	_t = _mm_shuffle_epi32(_t, 0xff);			\
-	rkeys[i] = _mm_xor_si128(_s, _t);			\
-} while (0)
-
-/**
- * crypto_aes_key_expand_128_aesni(key, rkeys):
- * Expand the 128-bit AES key ${key} into the 11 round keys ${rkeys}.  This
- * implementation uses x86 AESNI instructions, and should only be used if
- * CPUSUPPORT_X86_AESNI is defined and cpusupport_x86_aesni() returns nonzero.
- */
-static void
-crypto_aes_key_expand_128_aesni(const uint8_t key[16], __m128i rkeys[11])
-{
-
-	/* The first round key is just the key. */
-	/**
-	 * XXX Compiler breakage:
-	 * The intrinsic defined by Intel for _mm_loadu_si128 defines it as
-	 * taking a (const __m128i *) parameter.  This forces us to write a
-	 * bug: The cast to (const __m128i *) is invalid since it increases
-	 * the alignment requirement of the pointer.  Alas, until compilers
-	 * get fixed intrinsics, all we can do is code the bug and require
-	 * that alignment-requirement-increasing compiler warnings get
-	 * disabled.
-	 */
-	rkeys[0] = _mm_loadu_si128((const __m128i *)&key[0]);
-
-	/*
-	 * Each of the remaining round keys are computed from the preceding
-	 * round key: rotword+subword+rcon (provided as aeskeygenassist) to
-	 * compute the 'temp' value, then xor with 1, 2, 3, or all 4 of the
-	 * 32-bit words from the preceding round key.  Unfortunately, 'rcon'
-	 * is encoded as an immediate value, so we need to write the loop out
-	 * ourselves rather than allowing the compiler to expand it.
-	 */
-	MKRKEY128(rkeys, 1, 0x01);
-	MKRKEY128(rkeys, 2, 0x02);
-	MKRKEY128(rkeys, 3, 0x04);
-	MKRKEY128(rkeys, 4, 0x08);
-	MKRKEY128(rkeys, 5, 0x10);
-	MKRKEY128(rkeys, 6, 0x20);
-	MKRKEY128(rkeys, 7, 0x40);
-	MKRKEY128(rkeys, 8, 0x80);
-	MKRKEY128(rkeys, 9, 0x1b);
-	MKRKEY128(rkeys, 10, 0x36);
-}
-
-/* Compute an AES-256 round key. */
-#define MKRKEY256(rkeys, i, shuffle, rcon)	do {		\
-	__m128i _s = rkeys[i - 2];				\
-	__m128i _t = rkeys[i - 1];				\
-	_s = _mm_xor_si128(_s, _mm_slli_si128(_s, 4));		\
-	_s = _mm_xor_si128(_s, _mm_slli_si128(_s, 8));		\
-	_t = _mm_aeskeygenassist_si128(_t, rcon);		\
-	_t = _mm_shuffle_epi32(_t, shuffle);			\
-	rkeys[i] = _mm_xor_si128(_s, _t);			\
-} while (0)
-
-/**
- * crypto_aes_key_expand_256_aesni(key, rkeys):
- * Expand the 256-bit AES key ${key} into the 15 round keys ${rkeys}.  This
- * implementation uses x86 AESNI instructions, and should only be used if
- * CPUSUPPORT_X86_AESNI is defined and cpusupport_x86_aesni() returns nonzero.
- */
-static void
-crypto_aes_key_expand_256_aesni(const uint8_t key[32], __m128i rkeys[15])
-{
-
-	/* The first two round keys are just the key. */
-	/**
-	 * XXX Compiler breakage:
-	 * The intrinsic defined by Intel for _mm_loadu_si128 defines it as
-	 * taking a (const __m128i *) parameter.  This forces us to write a
-	 * bug: The cast to (const __m128i *) is invalid since it increases
-	 * the alignment requirement of the pointer.  Alas, until compilers
-	 * get fixed intrinsics, all we can do is code the bug and require
-	 * that alignment-requirement-increasing compiler warnings get
-	 * disabled.
-	 */
-	rkeys[0] = _mm_loadu_si128((const __m128i *)&key[0]);
-	rkeys[1] = _mm_loadu_si128((const __m128i *)&key[16]);
-
-	/*
-	 * Each of the remaining round keys are computed from the preceding
-	 * pair of keys.  Even rounds use rotword+subword+rcon, while odd
-	 * rounds just use subword; the aeskeygenassist instruction computes
-	 * both, and we use 0xff or 0xaa to select the one we need.  The rcon
-	 * value used is irrelevant for odd rounds since we ignore the value
-	 * which it feeds into.  Unfortunately, the 'shuffle' and 'rcon'
-	 * values are encoded into the instructions as immediates, so we need
-	 * to write the loop out ourselves rather than allowing the compiler
-	 * to expand it.
-	 */
-	MKRKEY256(rkeys, 2, 0xff, 0x01);
-	MKRKEY256(rkeys, 3, 0xaa, 0x00);
-	MKRKEY256(rkeys, 4, 0xff, 0x02);
-	MKRKEY256(rkeys, 5, 0xaa, 0x00);
-	MKRKEY256(rkeys, 6, 0xff, 0x04);
-	MKRKEY256(rkeys, 7, 0xaa, 0x00);
-	MKRKEY256(rkeys, 8, 0xff, 0x08);
-	MKRKEY256(rkeys, 9, 0xaa, 0x00);
-	MKRKEY256(rkeys, 10, 0xff, 0x10);
-	MKRKEY256(rkeys, 11, 0xaa, 0x00);
-	MKRKEY256(rkeys, 12, 0xff, 0x20);
-	MKRKEY256(rkeys, 13, 0xaa, 0x00);
-	MKRKEY256(rkeys, 14, 0xff, 0x40);
-}
-
-/**
- * crypto_aes_key_expand_aesni(key, len):
- * Expand the ${len}-byte AES key ${key} into a structure which can be passed
- * to crypto_aes_encrypt_block_aesni.  The length must be 16 or 32.  This
- * implementation uses x86 AESNI instructions, and should only be used if
- * CPUSUPPORT_X86_AESNI is defined and cpusupport_x86_aesni() returns nonzero.
- */
-void *
-crypto_aes_key_expand_aesni(const uint8_t * key, size_t len)
-{
-	struct crypto_aes_key_aesni * kexp;
-	size_t rkey_offset;
-
-	/* Allocate structure. */
-	if ((kexp = malloc(sizeof(struct crypto_aes_key_aesni))) == NULL)
-		goto err0;
-
-	/* Figure out where to put the round keys. */
-	rkey_offset = (uintptr_t)(&kexp->rkeys_buf[0]) % sizeof(__m128i);
-	rkey_offset = (sizeof(__m128i) - rkey_offset) % sizeof(__m128i);
-	kexp->rkeys = (void *)&kexp->rkeys_buf[rkey_offset];
-
-	/* Compute round keys. */
-	if (len == 16) {
-		kexp->nr = 10;
-		crypto_aes_key_expand_128_aesni(key, kexp->rkeys);
-	} else if (len == 32) {
-		kexp->nr = 14;
-		crypto_aes_key_expand_256_aesni(key, kexp->rkeys);
-	} else {
-		warn0("Unsupported AES key length: %zu bytes", len);
-		goto err1;
-	}
-
-	/* Success! */
-	return (kexp);
-
-err1:
-	free(kexp);
-err0:
-	/* Failure! */
-	return (NULL);
-}
-
-/**
- * crypto_aes_encrypt_block_aesni(in, out, key):
- * Using the expanded AES key ${key}, encrypt the block ${in} and write the
- * resulting ciphertext to ${out}.  This implementation uses x86 AESNI
- * instructions, and should only be used if CPUSUPPORT_X86_AESNI is defined
- * and cpusupport_x86_aesni() returns nonzero.
- */
-void
-crypto_aes_encrypt_block_aesni(const uint8_t * in, uint8_t * out,
-    const void * key)
-{
-	const struct crypto_aes_key_aesni * _key = key;
-	const __m128i * aes_key = _key->rkeys;
-	__m128i aes_state;
-	size_t nr = _key->nr;
-
-	aes_state = _mm_loadu_si128((const __m128i *)in);
-	aes_state = _mm_xor_si128(aes_state, aes_key[0]);
-	aes_state = _mm_aesenc_si128(aes_state, aes_key[1]);
-	aes_state = _mm_aesenc_si128(aes_state, aes_key[2]);
-	aes_state = _mm_aesenc_si128(aes_state, aes_key[3]);
-	aes_state = _mm_aesenc_si128(aes_state, aes_key[4]);
-	aes_state = _mm_aesenc_si128(aes_state, aes_key[5]);
-	aes_state = _mm_aesenc_si128(aes_state, aes_key[6]);
-	aes_state = _mm_aesenc_si128(aes_state, aes_key[7]);
-	aes_state = _mm_aesenc_si128(aes_state, aes_key[8]);
-	aes_state = _mm_aesenc_si128(aes_state, aes_key[9]);
-	if (nr > 10) {
-		aes_state = _mm_aesenc_si128(aes_state, aes_key[10]);
-		aes_state = _mm_aesenc_si128(aes_state, aes_key[11]);
-
-		if (nr > 12) {
-			aes_state = _mm_aesenc_si128(aes_state, aes_key[12]);
-			aes_state = _mm_aesenc_si128(aes_state, aes_key[13]);
-		}
-	}
-
-	aes_state = _mm_aesenclast_si128(aes_state, aes_key[nr]);
-	_mm_storeu_si128((__m128i *)out, aes_state);
-}
-
-/**
- * crypto_aes_key_free_aesni(key):
- * Free the expanded AES key ${key}.
- */
-void
-crypto_aes_key_free_aesni(void * key)
-{
-
-	/* Attempt to zero the expanded key. */
-	insecure_memzero(key, sizeof(struct crypto_aes_key_aesni));
-
-	/* Free the key. */
-	free(key);
-}
-
-#endif /* CPUSUPPORT_X86_AESNI */
diff -pruN 0.8.0-0.3/scrypt-1.2.0/libcperciva/crypto/crypto_aes_aesni.h 0.8.20-1/scrypt-1.2.0/libcperciva/crypto/crypto_aes_aesni.h
--- 0.8.0-0.3/scrypt-1.2.0/libcperciva/crypto/crypto_aes_aesni.h	2015-08-08 18:45:05.000000000 +0000
+++ 0.8.20-1/scrypt-1.2.0/libcperciva/crypto/crypto_aes_aesni.h	1970-01-01 00:00:00.000000000 +0000
@@ -1,31 +0,0 @@
-#ifndef _CRYPTO_AES_AESNI_H_
-#define _CRYPTO_AES_AESNI_H_
-
-#include <stddef.h>
-#include <stdint.h>
-
-/**
- * crypto_aes_key_expand_aesni(key, len):
- * Expand the ${len}-byte AES key ${key} into a structure which can be passed
- * to crypto_aes_encrypt_block_aesni.  The length must be 16 or 32.  This
- * implementation uses x86 AESNI instructions, and should only be used if
- * CPUSUPPORT_X86_AESNI is defined and cpusupport_x86_aesni() returns nonzero.
- */
-void * crypto_aes_key_expand_aesni(const uint8_t *, size_t);
-
-/**
- * crypto_aes_encrypt_block_aesni(in, out, key):
- * Using the expanded AES key ${key}, encrypt the block ${in} and write the
- * resulting ciphertext to ${out}.  This implementation uses x86 AESNI
- * instructions, and should only be used if CPUSUPPORT_X86_AESNI is defined
- * and cpusupport_x86_aesni() returns nonzero.
- */
-void crypto_aes_encrypt_block_aesni(const uint8_t *, uint8_t *, const void *);
-
-/**
- * crypto_aes_key_free_aesni(key):
- * Free the expanded AES key ${key}.
- */
-void crypto_aes_key_free_aesni(void *);
-
-#endif /* !_CRYPTO_AES_AESNI_H_ */
diff -pruN 0.8.0-0.3/scrypt-1.2.0/libcperciva/crypto/crypto_aes.c 0.8.20-1/scrypt-1.2.0/libcperciva/crypto/crypto_aes.c
--- 0.8.0-0.3/scrypt-1.2.0/libcperciva/crypto/crypto_aes.c	2015-08-08 18:45:05.000000000 +0000
+++ 0.8.20-1/scrypt-1.2.0/libcperciva/crypto/crypto_aes.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,166 +0,0 @@
-#include <assert.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <openssl/aes.h>
-
-#include "cpusupport.h"
-#include "crypto_aes_aesni.h"
-#include "insecure_memzero.h"
-#include "warnp.h"
-
-#include "crypto_aes.h"
-
-/**
- * This represents either an AES_KEY or a struct crypto_aes_key_aesni; we
- * know which it is based on whether we're using AESNI code or not.  As such,
- * it's just an opaque pointer; but declaring it as a named structure type
- * prevents type-mismatch bugs in upstream code.
- */
-struct crypto_aes_key;
-
-#ifdef CPUSUPPORT_X86_AESNI
-/* Test whether OpenSSL and AESNI code produce the same AES ciphertext. */
-static int
-aesnitest(uint8_t ptext[16], uint8_t * key, size_t keylen)
-{
-	AES_KEY kexp_openssl;
-	void * kexp_aesni;
-	uint8_t ctext_openssl[16];
-	uint8_t ctext_aesni[16];
-
-	/* Expand the key. */
-	AES_set_encrypt_key(key, keylen * 8, &kexp_openssl);
-	if ((kexp_aesni = crypto_aes_key_expand_aesni(key, keylen)) == NULL)
-		goto err0;
-
-	/* Encrypt the block. */
-	AES_encrypt(ptext, ctext_openssl, &kexp_openssl);
-	crypto_aes_encrypt_block_aesni(ptext, ctext_aesni, kexp_aesni);
-
-	/* Free the AESNI expanded key. */
-	crypto_aes_key_free_aesni(kexp_aesni);
-
-	/* Do the outputs match? */
-	return (memcmp(ctext_openssl, ctext_aesni, 16));
-
-err0:
-	/* Failure! */
-	return (-1);
-}
-
-/* Should we use AESNI? */
-static int
-useaesni(void)
-{
-	static int aesnigood = -1;
-	uint8_t key[32];
-	uint8_t ptext[16];
-	size_t i;
-
-	/* If we haven't decided which code to use yet, decide now. */
-	while (aesnigood == -1) {
-		/* Default to OpenSSL. */
-		aesnigood = 0;
-
-		/* If the CPU doesn't claim to support AESNI, stop here. */
-		if (!cpusupport_x86_aesni())
-			break;
-
-		/* Test cases: key is 0x00010203..., ptext is 0x00112233... */
-		for (i = 0; i < 16; i++)
-			ptext[i] = 0x11 * i;
-		for (i = 0; i < 32; i++)
-			key[i] = i;
-
-		/* Test that AESNI and OpenSSL produce the same results. */
-		if (aesnitest(ptext, key, 16) || aesnitest(ptext, key, 32)) {
-			warn0("Disabling AESNI due to failed self-test");
-			break;
-		}
-
-		/* AESNI works; use it. */
-		aesnigood = 1;
-	}
-
-	return (aesnigood);
-}
-#endif /* CPUSUPPORT_X86_AESNI */
-
-/**
- * crypto_aes_key_expand(key, len):
- * Expand the ${len}-byte AES key ${key} into a structure which can be passed
- * to crypto_aes_encrypt_block.  The length must be 16 or 32.
- */
-struct crypto_aes_key *
-crypto_aes_key_expand(const uint8_t * key, size_t len)
-{
-	AES_KEY * kexp;
-
-	/* Sanity-check. */
-	assert((len == 16) || (len == 32));
-
-#ifdef CPUSUPPORT_X86_AESNI
-	/* Use AESNI if we can. */
-	if (useaesni())
-		return (crypto_aes_key_expand_aesni(key, len));
-#endif
-
-	/* Allocate structure. */
-	if ((kexp = malloc(sizeof(AES_KEY))) == NULL)
-		goto err0;
-
-	/* Expand the key. */
-	AES_set_encrypt_key(key, len * 8, kexp);
-
-	/* Success! */
-	return ((void *)kexp);
-
-err0:
-	/* Failure! */
-	return (NULL);
-}
-
-/**
- * crypto_aes_encrypt_block(in, out, key):
- * Using the expanded AES key ${key}, encrypt the block ${in} and write the
- * resulting ciphertext to ${out}.
- */
-void
-crypto_aes_encrypt_block(const uint8_t * in, uint8_t * out,
-    const struct crypto_aes_key * key)
-{
-
-#ifdef CPUSUPPORT_X86_AESNI
-	if (useaesni()) {
-		crypto_aes_encrypt_block_aesni(in, out, (const void *)key);
-		return;
-	}
-#endif
-
-	/* Get AES to do the work. */
-	AES_encrypt(in, out, (const void *)key);
-}
-
-/**
- * crypto_aes_key_free(key):
- * Free the expanded AES key ${key}.
- */
-void
-crypto_aes_key_free(struct crypto_aes_key * key)
-{
-
-#ifdef CPUSUPPORT_X86_AESNI
-	if (useaesni()) {
-		crypto_aes_key_free_aesni((void *)key);
-		return;
-	}
-#endif
-
-	/* Attempt to zero the expanded key. */
-	insecure_memzero(key, sizeof(AES_KEY));
-
-	/* Free the key. */
-	free(key);
-}
diff -pruN 0.8.0-0.3/scrypt-1.2.0/libcperciva/crypto/crypto_aesctr.c 0.8.20-1/scrypt-1.2.0/libcperciva/crypto/crypto_aesctr.c
--- 0.8.0-0.3/scrypt-1.2.0/libcperciva/crypto/crypto_aesctr.c	2015-08-08 18:45:05.000000000 +0000
+++ 0.8.20-1/scrypt-1.2.0/libcperciva/crypto/crypto_aesctr.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,124 +0,0 @@
-#include <stdint.h>
-#include <stdlib.h>
-
-#include "crypto_aes.h"
-#include "sysendian.h"
-
-#include "crypto_aesctr.h"
-
-struct crypto_aesctr {
-	const struct crypto_aes_key * key;
-	uint64_t nonce;
-	uint64_t bytectr;
-	uint8_t buf[16];
-};
-
-/**
- * crypto_aesctr_init(key, nonce):
- * Prepare to encrypt/decrypt data with AES in CTR mode, using the provided
- * expanded key and nonce.  The key provided must remain valid for the
- * lifetime of the stream.
- */
-struct crypto_aesctr *
-crypto_aesctr_init(const struct crypto_aes_key * key, uint64_t nonce)
-{
-	struct crypto_aesctr * stream;
-
-	/* Allocate memory. */
-	if ((stream = malloc(sizeof(struct crypto_aesctr))) == NULL)
-		goto err0;
-
-	/* Initialize values. */
-	stream->key = key;
-	stream->nonce = nonce;
-	stream->bytectr = 0;
-
-	/* Success! */
-	return (stream);
-
-err0:
-	/* Failure! */
-	return (NULL);
-}
-
-/**
- * crypto_aesctr_stream(stream, inbuf, outbuf, buflen):
- * Generate the next ${buflen} bytes of the AES-CTR stream and xor them with
- * bytes from ${inbuf}, writing the result into ${outbuf}.  If the buffers
- * ${inbuf} and ${outbuf} overlap, they must be identical.
- */
-void
-crypto_aesctr_stream(struct crypto_aesctr * stream, const uint8_t * inbuf,
-    uint8_t * outbuf, size_t buflen)
-{
-	uint8_t pblk[16];
-	size_t pos;
-	int bytemod;
-
-	for (pos = 0; pos < buflen; pos++) {
-		/* How far through the buffer are we? */
-		bytemod = stream->bytectr % 16;
-
-		/* Generate a block of cipherstream if needed. */
-		if (bytemod == 0) {
-			be64enc(pblk, stream->nonce);
-			be64enc(pblk + 8, stream->bytectr / 16);
-			crypto_aes_encrypt_block(pblk, stream->buf,
-			    stream->key);
-		}
-
-		/* Encrypt a byte. */
-		outbuf[pos] = inbuf[pos] ^ stream->buf[bytemod];
-
-		/* Move to the next byte of cipherstream. */
-		stream->bytectr += 1;
-	}
-}
-
-/**
- * crypto_aesctr_free(stream):
- * Free the provided stream object.
- */
-void
-crypto_aesctr_free(struct crypto_aesctr * stream)
-{
-	int i;
-
-	/* Be compatible with free(NULL). */
-	if (stream == NULL)
-		return;
-
-	/* Zero potentially sensitive information. */
-	for (i = 0; i < 16; i++)
-		stream->buf[i] = 0;
-	stream->bytectr = stream->nonce = 0;
-
-	/* Free the stream. */
-	free(stream);
-}
-
-/**
- * crypto_aesctr_buf(key, nonce, inbuf, outbuf, buflen):
- * Equivalent to init(key, nonce); stream(inbuf, outbuf, buflen); free.
- */
-void
-crypto_aesctr_buf(const struct crypto_aes_key * key, uint64_t nonce,
-    const uint8_t * inbuf, uint8_t * outbuf, size_t buflen)
-{
-	struct crypto_aesctr stream_rec;
-	struct crypto_aesctr * stream = &stream_rec;
-	int i;
-
-	/* Initialize values. */
-	stream->key = key;
-	stream->nonce = nonce;
-	stream->bytectr = 0;
-
-	/* Perform the encryption. */
-	crypto_aesctr_stream(stream, inbuf, outbuf, buflen);
-
-	/* Zero potentially sensitive information. */
-	for (i = 0; i < 16; i++)
-		stream->buf[i] = 0;
-	stream->bytectr = stream->nonce = 0;
-}
diff -pruN 0.8.0-0.3/scrypt-1.2.0/libcperciva/crypto/crypto_aesctr.h 0.8.20-1/scrypt-1.2.0/libcperciva/crypto/crypto_aesctr.h
--- 0.8.0-0.3/scrypt-1.2.0/libcperciva/crypto/crypto_aesctr.h	2015-08-08 18:45:05.000000000 +0000
+++ 0.8.20-1/scrypt-1.2.0/libcperciva/crypto/crypto_aesctr.h	1970-01-01 00:00:00.000000000 +0000
@@ -1,41 +0,0 @@
-#ifndef _CRYPTO_AESCTR_H_
-#define _CRYPTO_AESCTR_H_
-
-#include <stddef.h>
-#include <stdint.h>
-
-/* Opaque type. */
-struct crypto_aes_key;
-
-/**
- * crypto_aesctr_init(key, nonce):
- * Prepare to encrypt/decrypt data with AES in CTR mode, using the provided
- * expanded key and nonce.  The key provided must remain valid for the
- * lifetime of the stream.
- */
-struct crypto_aesctr * crypto_aesctr_init(const struct crypto_aes_key *,
-    uint64_t);
-
-/**
- * crypto_aesctr_stream(stream, inbuf, outbuf, buflen):
- * Generate the next ${buflen} bytes of the AES-CTR stream and xor them with
- * bytes from ${inbuf}, writing the result into ${outbuf}.  If the buffers
- * ${inbuf} and ${outbuf} overlap, they must be identical.
- */
-void crypto_aesctr_stream(struct crypto_aesctr *, const uint8_t *,
-    uint8_t *, size_t);
-
-/**
- * crypto_aesctr_free(stream):
- * Free the provided stream object.
- */
-void crypto_aesctr_free(struct crypto_aesctr *);
-
-/**
- * crypto_aesctr_buf(key, nonce, inbuf, outbuf, buflen):
- * Equivalent to init(key, nonce); stream(inbuf, outbuf, buflen); free.
- */
-void crypto_aesctr_buf(const struct crypto_aes_key *, uint64_t,
-    const uint8_t *, uint8_t *, size_t);
-
-#endif /* !_CRYPTO_AESCTR_H_ */
diff -pruN 0.8.0-0.3/scrypt-1.2.0/libcperciva/crypto/crypto_aes.h 0.8.20-1/scrypt-1.2.0/libcperciva/crypto/crypto_aes.h
--- 0.8.0-0.3/scrypt-1.2.0/libcperciva/crypto/crypto_aes.h	2015-08-08 18:45:05.000000000 +0000
+++ 0.8.20-1/scrypt-1.2.0/libcperciva/crypto/crypto_aes.h	1970-01-01 00:00:00.000000000 +0000
@@ -1,31 +0,0 @@
-#ifndef _CRYPTO_AES_H_
-#define _CRYPTO_AES_H_
-
-#include <stddef.h>
-#include <stdint.h>
-
-/* Opaque structure. */
-struct crypto_aes_key;
-
-/**
- * crypto_aes_key_expand(key, len):
- * Expand the ${len}-byte AES key ${key} into a structure which can be passed
- * to crypto_aes_encrypt_block.  The length must be 16 or 32.
- */
-struct crypto_aes_key * crypto_aes_key_expand(const uint8_t *, size_t);
-
-/**
- * crypto_aes_encrypt_block(in, out, key):
- * Using the expanded AES key ${key}, encrypt the block ${in} and write the
- * resulting ciphertext to ${out}.
- */
-void crypto_aes_encrypt_block(const uint8_t *, uint8_t *,
-    const struct crypto_aes_key *);
-
-/**
- * crypto_aes_key_free(key):
- * Free the expanded AES key ${key}.
- */
-void crypto_aes_key_free(struct crypto_aes_key *);
-
-#endif /* !_CRYPTO_AES_H_ */
diff -pruN 0.8.0-0.3/scrypt-1.2.0/libcperciva/crypto/crypto_entropy.c 0.8.20-1/scrypt-1.2.0/libcperciva/crypto/crypto_entropy.c
--- 0.8.0-0.3/scrypt-1.2.0/libcperciva/crypto/crypto_entropy.c	2015-08-08 18:45:05.000000000 +0000
+++ 0.8.20-1/scrypt-1.2.0/libcperciva/crypto/crypto_entropy.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,215 +0,0 @@
-#include <assert.h>
-#include <stdint.h>
-#include <string.h>
-
-#include "entropy.h"
-#include "insecure_memzero.h"
-
-#include "sha256.h"
-
-#include "crypto_entropy.h"
-
-/**
- * This system implements the HMAC_DRBG pseudo-random number generator as
- * specified in section 10.1.2 of the NIST SP 800-90 standard.  In this
- * implementation, the optional personalization_string and additional_input
- * specified in the standard are not implemented.
- */
-
-/* Internal HMAC_DRBG state. */
-static struct {
-	uint8_t Key[32];
-	uint8_t V[32];
-	uint32_t reseed_counter;
-} drbg;
-
-/* Set to non-zero once the PRNG has been instantiated. */
-static int instantiated = 0;
-
-/* Could be as high as 2^48 if we wanted... */
-#define RESEED_INTERVAL	256
-
-/* Limited to 2^16 by specification. */
-#define GENERATE_MAXLEN	65536
-
-static int instantiate(void);
-static void update(uint8_t *, size_t);
-static int reseed(void);
-static void generate(uint8_t *, size_t);
-
-/**
- * instantiate(void):
- * Initialize the DRBG state.  (Section 10.1.2.3)
- */
-static int
-instantiate(void)
-{
-	uint8_t seed_material[48];
-
-	/* Obtain random seed_material = (entropy_input || nonce). */
-	if (entropy_read(seed_material, 48))
-		return (-1);
-
-	/* Initialize Key, V, and reseed_counter. */
-	memset(drbg.Key, 0x00, 32);
-	memset(drbg.V, 0x01, 32);
-	drbg.reseed_counter = 1;
-
-	/* Mix the random seed into the state. */
-	update(seed_material, 48);
-
-	/* Clean the stack. */
-	insecure_memzero(seed_material, 48);
-
-	/* Success! */
-	return (0);
-}
-
-/**
- * update(data, datalen):
- * Update the DRBG state using the provided data.  (Section 10.1.2.2)
- */
-static void
-update(uint8_t * data, size_t datalen)
-{
-	HMAC_SHA256_CTX ctx;
-	uint8_t K[32];
-	uint8_t Vx[33];
-
-	/* Load (Key, V) into (K, Vx). */
-	memcpy(K, drbg.Key, 32);
-	memcpy(Vx, drbg.V, 32);
-
-	/* K <- HMAC(K, V || 0x00 || data). */
-	Vx[32] = 0x00;
-	HMAC_SHA256_Init(&ctx, K, 32);
-	HMAC_SHA256_Update(&ctx, Vx, 33);
-	HMAC_SHA256_Update(&ctx, data, datalen);
-	HMAC_SHA256_Final(K, &ctx);
-
-	/* V <- HMAC(K, V). */
-	HMAC_SHA256_Buf(K, 32, Vx, 32, Vx);
-
-	/* If the provided data is non-Null, perform another mixing stage. */
-	if (datalen != 0) {
-		/* K <- HMAC(K, V || 0x01 || data). */
-		Vx[32] = 0x01;
-		HMAC_SHA256_Init(&ctx, K, 32);
-		HMAC_SHA256_Update(&ctx, Vx, 33);
-		HMAC_SHA256_Update(&ctx, data, datalen);
-		HMAC_SHA256_Final(K, &ctx);
-
-		/* V <- HMAC(K, V). */
-		HMAC_SHA256_Buf(K, 32, Vx, 32, Vx);
-	}
-
-	/* Copy (K, Vx) back to (Key, V). */
-	memcpy(drbg.Key, K, 32);
-	memcpy(drbg.V, Vx, 32);
-
-	/* Clean the stack. */
-	insecure_memzero(K, 32);
-	insecure_memzero(Vx, 33);
-}
-
-/**
- * reseed(void):
- * Reseed the DRBG state (mix in new entropy).  (Section 10.1.2.4)
- */
-static int
-reseed(void)
-{
-	uint8_t seed_material[32];
-
-	/* Obtain random seed_material = entropy_input. */
-	if (entropy_read(seed_material, 32))
-		return (-1);
-
-	/* Mix the random seed into the state. */
-	update(seed_material, 32);
-
-	/* Reset the reseed_counter. */
-	drbg.reseed_counter = 1;
-
-	/* Clean the stack. */
-	insecure_memzero(seed_material, 32);
-
-	/* Success! */
-	return (0);
-}
-
-/**
- * generate(buf, buflen):
- * Fill the provided buffer with random bits, assuming that reseed_counter
- * is less than RESEED_INTERVAL (the caller is responsible for calling
- * reseed() as needed) and ${buflen} is less than 2^16 (the caller is
- * responsible for splitting up larger requests).  (Section 10.1.2.5)
- */
-static void
-generate(uint8_t * buf, size_t buflen)
-{
-	size_t bufpos;
-
-	assert(buflen <= GENERATE_MAXLEN);
-	assert(drbg.reseed_counter <= RESEED_INTERVAL);
-
-	/* Iterate until we've filled the buffer. */
-	for (bufpos = 0; bufpos < buflen; bufpos += 32) {
-		HMAC_SHA256_Buf(drbg.Key, 32, drbg.V, 32, drbg.V);
-		if (buflen - bufpos >= 32)
-			memcpy(&buf[bufpos], drbg.V, 32);
-		else
-			memcpy(&buf[bufpos], drbg.V, buflen - bufpos);
-	}
-
-	/* Mix up state. */
-	update(NULL, 0);
-
-	/* We're one data-generation step closer to needing a reseed. */
-	drbg.reseed_counter += 1;
-}
-
-/**
- * crypto_entropy_read(buf, buflen):
- * Fill the buffer with unpredictable bits.
- */
-int
-crypto_entropy_read(uint8_t * buf, size_t buflen)
-{
-	size_t bytes_to_provide;
-
-	/* Instantiate if needed. */
-	if (instantiated == 0) {
-		/* Try to instantiate the PRNG. */
-		if (instantiate())
-			return (-1);
-
-		/* We have instantiated the PRNG. */
-		instantiated = 1;
-	}
-
-	/* Loop until we've filled the buffer. */
-	while (buflen > 0) {
-		/* Do we need to reseed? */
-		if (drbg.reseed_counter > RESEED_INTERVAL) {
-			if (reseed())
-				return (-1);
-		}
-
-		/* How much data are we generating in this step? */
-		if (buflen > GENERATE_MAXLEN)
-			bytes_to_provide = GENERATE_MAXLEN;
-		else
-			bytes_to_provide = buflen;
-
-		/* Generate bytes. */
-		generate(buf, bytes_to_provide);
-
-		/* We've done part of the buffer. */
-		buf += bytes_to_provide;
-		buflen -= bytes_to_provide;
-	}
-
-	/* Success! */
-	return (0);
-}
diff -pruN 0.8.0-0.3/scrypt-1.2.0/libcperciva/crypto/crypto_entropy.h 0.8.20-1/scrypt-1.2.0/libcperciva/crypto/crypto_entropy.h
--- 0.8.0-0.3/scrypt-1.2.0/libcperciva/crypto/crypto_entropy.h	2015-08-08 18:45:05.000000000 +0000
+++ 0.8.20-1/scrypt-1.2.0/libcperciva/crypto/crypto_entropy.h	1970-01-01 00:00:00.000000000 +0000
@@ -1,14 +0,0 @@
-#ifndef _CRYPTO_ENTROPY_H_
-#define _CRYPTO_ENTROPY_H_
-
-#include <stddef.h>
-#include <stdint.h>
-
-/**
- * crypto_entropy_read(buf, buflen):
- * Fill the buffer with unpredictable bits.  The value ${buflen} must be
- * less than 2^16.
- */
-int crypto_entropy_read(uint8_t *, size_t);
-
-#endif /* !_CRYPTO_ENTROPY_H_ */
diff -pruN 0.8.0-0.3/scrypt-1.2.0/libcperciva/util/entropy.c 0.8.20-1/scrypt-1.2.0/libcperciva/util/entropy.c
--- 0.8.0-0.3/scrypt-1.2.0/libcperciva/util/entropy.c	2016-09-17 13:00:50.000000000 +0000
+++ 0.8.20-1/scrypt-1.2.0/libcperciva/util/entropy.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,105 +0,0 @@
-#include <fcntl.h>
-#include <limits.h>
-#include <stdint.h>
-#include <unistd.h>
-
-#include "warnp.h"
-
-#include "entropy.h"
-
-#ifdef _WIN32
-#include <windows.h>
-#include <Wincrypt.h>
-#endif
-
-/**
- * XXX Portability
- * XXX We obtain random bytes from the operating system by opening
- * XXX /dev/urandom and reading them from that device; this works on
- * XXX modern UNIX-like operating systems but not on systems like
- * XXX win32 where there is no concept of /dev/urandom.
- */
-
-/**
- * entropy_read(buf, buflen):
- * Fill the given buffer with random bytes provided by the operating system.
- */
-int
-entropy_read(uint8_t * buf, size_t buflen)
-{
-	int fd;
-	ssize_t lenread;
-
-#ifndef _WIN32
-	/* Sanity-check the buffer size. */
-	if (buflen > SSIZE_MAX) {
-		warn0("Programmer error: "
-		    "Trying to read insane amount of random data: %zu",
-		    buflen);
-		goto err0;
-	}
-
-	/* Open /dev/urandom. */
-	if ((fd = open("/dev/urandom", O_RDONLY)) == -1) {
-		warnp("open(/dev/urandom)");
-		goto err0;
-	}
-
-	/* Read bytes until we have filled the buffer. */
-	while (buflen > 0) {
-		if ((lenread = read(fd, buf, buflen)) == -1) {
-			warnp("read(/dev/urandom)");
-			goto err1;
-		}
-
-		/* The random device should never EOF. */
-		if (lenread == 0) {
-			warn0("EOF on /dev/urandom?");
-			goto err1;
-		}
-
-		/* We've filled a portion of the buffer. */
-		buf += lenread;
-		buflen -= lenread;
-	}
-
-	/* Close the device. */
-	while (close(fd) == -1) {
-		if (errno != EINTR) {
-			warnp("close(/dev/urandom)");
-			goto err0;
-		}
-	}
-
-	/* Success! */
-	return (0);
-
-err1:
-	close(fd);
-err0:
-	/* Failure! */
-	return (-1);
-
-#else // _WIN32
-
-    HCRYPTPROV context;
-	DWORD error;
-
-    if(CryptAcquireContext(&context, NULL, NULL, PROV_RSA_AES, 0) == NTE_BAD_KEYSET)
-    {
-		if(!CryptAcquireContext(&context, NULL, NULL, PROV_RSA_AES, CRYPT_NEWKEYSET))
-		{
-			error = GetLastError();
-			return (-1);
-		}
-	}
-
-    if(CryptGenRandom(context, 32, buf))
-    {
-        buf += 32;
-        return (0);
-    }
-    else{return(-1);}
-
-#endif // _WIN32
-}
diff -pruN 0.8.0-0.3/scrypt-1.2.0/libcperciva/util/entropy.h 0.8.20-1/scrypt-1.2.0/libcperciva/util/entropy.h
--- 0.8.0-0.3/scrypt-1.2.0/libcperciva/util/entropy.h	2015-08-08 18:45:05.000000000 +0000
+++ 0.8.20-1/scrypt-1.2.0/libcperciva/util/entropy.h	1970-01-01 00:00:00.000000000 +0000
@@ -1,13 +0,0 @@
-#ifndef _ENTROPY_H_
-#define _ENTROPY_H_
-
-#include <stddef.h>
-#include <stdint.h>
-
-/**
- * entropy_read(buf, buflen):
- * Fill the given buffer with random bytes provided by the operating system.
- */
-int entropy_read(uint8_t *, size_t);
-
-#endif /* !_ENTROPY_H_ */
diff -pruN 0.8.0-0.3/scrypt-1.2.0/libcperciva/util/insecure_memzero.c 0.8.20-1/scrypt-1.2.0/libcperciva/util/insecure_memzero.c
--- 0.8.0-0.3/scrypt-1.2.0/libcperciva/util/insecure_memzero.c	2015-08-08 18:45:05.000000000 +0000
+++ 0.8.20-1/scrypt-1.2.0/libcperciva/util/insecure_memzero.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,19 +0,0 @@
-#include <stddef.h>
-#include <stdint.h>
-
-#include "insecure_memzero.h"
-
-/* Function which does the zeroing. */
-static void
-insecure_memzero_func(volatile void * buf, size_t len)
-{
-	volatile uint8_t * _buf = buf;
-	size_t i;
-
-	for (i = 0; i < len; i++)
-		_buf[i] = 0;
-}
-
-/* Pointer to memory-zeroing function. */
-void (* volatile insecure_memzero_ptr)(volatile void *, size_t) =
-    insecure_memzero_func;
diff -pruN 0.8.0-0.3/scrypt-1.2.0/libcperciva/util/insecure_memzero.h 0.8.20-1/scrypt-1.2.0/libcperciva/util/insecure_memzero.h
--- 0.8.0-0.3/scrypt-1.2.0/libcperciva/util/insecure_memzero.h	2015-08-08 18:45:05.000000000 +0000
+++ 0.8.20-1/scrypt-1.2.0/libcperciva/util/insecure_memzero.h	1970-01-01 00:00:00.000000000 +0000
@@ -1,37 +0,0 @@
-#ifndef _INSECURE_MEMZERO_H_
-#define _INSECURE_MEMZERO_H_
-
-#include <stddef.h>
-
-/* Pointer to memory-zeroing function. */
-extern void (* volatile insecure_memzero_ptr)(volatile void *, size_t);
-
-/**
- * insecure_memzero(buf, len):
- * Attempt to zero ${len} bytes at ${buf} in spite of optimizing compilers'
- * best (standards-compliant) attempts to remove the buffer-zeroing.  In
- * particular, to avoid performing the zeroing, a compiler would need to
- * use optimistic devirtualization; recognize that non-volatile objects do not
- * need to be treated as volatile, even if they are accessed via volatile
- * qualified pointers; and perform link-time optimization; in addition to the
- * dead-code elimination which often causes buffer-zeroing to be elided.
- *
- * Note however that zeroing a buffer does not guarantee that the data held
- * in the buffer is not stored elsewhere; in particular, there may be copies
- * held in CPU registers or in anonymous allocations on the stack, even if
- * every named variable is successfully sanitized.  Solving the "wipe data
- * from the system" problem will require a C language extension which does not
- * yet exist.
- *
- * For more information, see:
- * http://www.daemonology.net/blog/2014-09-04-how-to-zero-a-buffer.html
- * http://www.daemonology.net/blog/2014-09-06-zeroing-buffers-is-insufficient.html
- */
-static inline void
-insecure_memzero(volatile void * buf, size_t len)
-{
-
-	(insecure_memzero_ptr)(buf, len);
-}
-
-#endif /* !_INSECURE_MEMZERO_H_ */
diff -pruN 0.8.0-0.3/scrypt-1.2.0/libcperciva/util/sysendian.h 0.8.20-1/scrypt-1.2.0/libcperciva/util/sysendian.h
--- 0.8.0-0.3/scrypt-1.2.0/libcperciva/util/sysendian.h	2015-08-08 18:45:05.000000000 +0000
+++ 0.8.20-1/scrypt-1.2.0/libcperciva/util/sysendian.h	1970-01-01 00:00:00.000000000 +0000
@@ -1,146 +0,0 @@
-#ifndef _SYSENDIAN_H_
-#define _SYSENDIAN_H_
-
-#include <stdint.h>
-
-/* Avoid namespace collisions with BSD <sys/endian.h>. */
-#define be16dec libcperciva_be16dec
-#define be16enc libcperciva_be16enc
-#define be32dec libcperciva_be32dec
-#define be32enc libcperciva_be32enc
-#define be64dec libcperciva_be64dec
-#define be64enc libcperciva_be64enc
-#define le16dec libcperciva_le16dec
-#define le16enc libcperciva_le16enc
-#define le32dec libcperciva_le32dec
-#define le32enc libcperciva_le32enc
-#define le64dec libcperciva_le64dec
-#define le64enc libcperciva_le64enc
-
-static inline uint16_t
-be16dec(const void * pp)
-{
-	const uint8_t * p = (uint8_t const *)pp;
-
-	return ((uint16_t)(p[1]) + ((uint16_t)(p[0]) << 8));
-}
-
-static inline void
-be16enc(void * pp, uint16_t x)
-{
-	uint8_t * p = (uint8_t *)pp;
-
-	p[1] = x & 0xff;
-	p[0] = (x >> 8) & 0xff;
-}
-
-static inline uint32_t
-be32dec(const void * pp)
-{
-	const uint8_t * p = (uint8_t const *)pp;
-
-	return ((uint32_t)(p[3]) + ((uint32_t)(p[2]) << 8) +
-	    ((uint32_t)(p[1]) << 16) + ((uint32_t)(p[0]) << 24));
-}
-
-static inline void
-be32enc(void * pp, uint32_t x)
-{
-	uint8_t * p = (uint8_t *)pp;
-
-	p[3] = x & 0xff;
-	p[2] = (x >> 8) & 0xff;
-	p[1] = (x >> 16) & 0xff;
-	p[0] = (x >> 24) & 0xff;
-}
-
-static inline uint64_t
-be64dec(const void * pp)
-{
-	const uint8_t * p = (uint8_t const *)pp;
-
-	return ((uint64_t)(p[7]) + ((uint64_t)(p[6]) << 8) +
-	    ((uint64_t)(p[5]) << 16) + ((uint64_t)(p[4]) << 24) +
-	    ((uint64_t)(p[3]) << 32) + ((uint64_t)(p[2]) << 40) +
-	    ((uint64_t)(p[1]) << 48) + ((uint64_t)(p[0]) << 56));
-}
-
-static inline void
-be64enc(void * pp, uint64_t x)
-{
-	uint8_t * p = (uint8_t *)pp;
-
-	p[7] = x & 0xff;
-	p[6] = (x >> 8) & 0xff;
-	p[5] = (x >> 16) & 0xff;
-	p[4] = (x >> 24) & 0xff;
-	p[3] = (x >> 32) & 0xff;
-	p[2] = (x >> 40) & 0xff;
-	p[1] = (x >> 48) & 0xff;
-	p[0] = (x >> 56) & 0xff;
-}
-
-static inline uint16_t
-le16dec(const void * pp)
-{
-	const uint8_t * p = (uint8_t const *)pp;
-
-	return ((uint16_t)(p[0]) + ((uint16_t)(p[1]) << 8));
-}
-
-static inline void
-le16enc(void * pp, uint16_t x)
-{
-	uint8_t * p = (uint8_t *)pp;
-
-	p[0] = x & 0xff;
-	p[1] = (x >> 8) & 0xff;
-}
-
-static inline uint32_t
-le32dec(const void * pp)
-{
-	const uint8_t * p = (uint8_t const *)pp;
-
-	return ((uint32_t)(p[0]) + ((uint32_t)(p[1]) << 8) +
-	    ((uint32_t)(p[2]) << 16) + ((uint32_t)(p[3]) << 24));
-}
-
-static inline void
-le32enc(void * pp, uint32_t x)
-{
-	uint8_t * p = (uint8_t *)pp;
-
-	p[0] = x & 0xff;
-	p[1] = (x >> 8) & 0xff;
-	p[2] = (x >> 16) & 0xff;
-	p[3] = (x >> 24) & 0xff;
-}
-
-static inline uint64_t
-le64dec(const void * pp)
-{
-	const uint8_t * p = (uint8_t const *)pp;
-
-	return ((uint64_t)(p[0]) + ((uint64_t)(p[1]) << 8) +
-	    ((uint64_t)(p[2]) << 16) + ((uint64_t)(p[3]) << 24) +
-	    ((uint64_t)(p[4]) << 32) + ((uint64_t)(p[5]) << 40) +
-	    ((uint64_t)(p[6]) << 48) + ((uint64_t)(p[7]) << 56));
-}
-
-static inline void
-le64enc(void * pp, uint64_t x)
-{
-	uint8_t * p = (uint8_t *)pp;
-
-	p[0] = x & 0xff;
-	p[1] = (x >> 8) & 0xff;
-	p[2] = (x >> 16) & 0xff;
-	p[3] = (x >> 24) & 0xff;
-	p[4] = (x >> 32) & 0xff;
-	p[5] = (x >> 40) & 0xff;
-	p[6] = (x >> 48) & 0xff;
-	p[7] = (x >> 56) & 0xff;
-}
-
-#endif /* !_SYSENDIAN_H_ */
diff -pruN 0.8.0-0.3/scrypt-1.2.0/libcperciva/util/warnp.c 0.8.20-1/scrypt-1.2.0/libcperciva/util/warnp.c
--- 0.8.0-0.3/scrypt-1.2.0/libcperciva/util/warnp.c	2015-08-08 18:45:05.000000000 +0000
+++ 0.8.20-1/scrypt-1.2.0/libcperciva/util/warnp.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,76 +0,0 @@
-#include <errno.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "warnp.h"
-
-static int initialized = 0;
-static char * name = NULL;
-
-/* Free the name string. */
-static void
-done(void)
-{
-
-	free(name);
-	name = NULL;
-}
-
-/**
- * warnp_setprogname(progname):
- * Set the program name to be used by warn() and warnx() to ${progname}.
- */
-void
-warnp_setprogname(const char * progname)
-{
-	const char * p;
-
-	/* Free the name if we already have one. */
-	free(name);
-
-	/* Find the last segment of the program name. */
-	for (p = progname; progname[0] != '\0'; progname++)
-		if (progname[0] == '/')
-			p = progname + 1;
-
-	/* Copy the name string. */
-	name = strdup(p);
-
-	/* If we haven't already done so, register our exit handler. */
-	if (initialized == 0) {
-		atexit(done);
-		initialized = 1;
-	}
-}
-
-void
-warn(const char * fmt, ...)
-{
-	va_list ap;
-
-	va_start(ap, fmt);
-	fprintf(stderr, "%s", (name != NULL) ? name : "(unknown)");
-	if (fmt != NULL) {
-		fprintf(stderr, ": ");
-		vfprintf(stderr, fmt, ap);
-	}
-	fprintf(stderr, ": %s\n", strerror(errno));
-	va_end(ap);
-}
-
-void
-warnx(const char * fmt, ...)
-{
-	va_list ap;
-
-	va_start(ap, fmt);
-	fprintf(stderr, "%s", (name != NULL) ? name : "(unknown)");
-	if (fmt != NULL) {
-		fprintf(stderr, ": ");
-		vfprintf(stderr, fmt, ap);
-	}
-	fprintf(stderr, "\n");
-	va_end(ap);
-}
diff -pruN 0.8.0-0.3/scrypt-1.2.0/libcperciva/util/warnp.h 0.8.20-1/scrypt-1.2.0/libcperciva/util/warnp.h
--- 0.8.0-0.3/scrypt-1.2.0/libcperciva/util/warnp.h	2015-08-08 18:45:05.000000000 +0000
+++ 0.8.20-1/scrypt-1.2.0/libcperciva/util/warnp.h	1970-01-01 00:00:00.000000000 +0000
@@ -1,59 +0,0 @@
-#ifndef _WARNP_H_
-#define _WARNP_H_
-
-#include <errno.h>
-
-/* Avoid namespace collisions with BSD <err.h>. */
-#define warn libcperciva_warn
-#define warnx libcperciva_warnx
-
-/**
- * warnp_setprogname(progname):
- * Set the program name to be used by warn() and warnx() to ${progname}.
- */
-void warnp_setprogname(const char *);
-#define WARNP_INIT	do {		\
-	if (argv[0] != NULL)		\
-		warnp_setprogname(argv[0]);	\
-} while (0)
-
-/* As in BSD <err.h>. */
-void warn(const char *, ...);
-void warnx(const char *, ...);
-
-/*
- * If compiled with DEBUG defined, print __FILE__ and __LINE__.
- */
-#ifdef DEBUG
-#define warnline	do {				\
-	warnx("%s, %d", __FILE__, __LINE__);	\
-} while (0)
-#else
-#define warnline
-#endif
-
-/*
- * Call warn(3) or warnx(3) depending upon whether errno == 0; and clear
- * errno (so that the standard error message isn't repeated later).
- */
-#define	warnp(...) do {					\
-	warnline;					\
-	if (errno != 0) {				\
-		warn(__VA_ARGS__);		\
-		errno = 0;				\
-	} else						\
-		warnx(__VA_ARGS__);		\
-} while (0)
-
-/*
- * Call warnx(3) and set errno == 0.  Unlike warnp, this should be used
- * in cases where we're reporting a problem which we discover ourselves
- * rather than one which is reported to us from a library or the kernel.
- */
-#define warn0(...) do {					\
-	warnline;					\
-	warnx(__VA_ARGS__);			\
-	errno = 0;					\
-} while (0)
-
-#endif /* !_WARNP_H_ */
diff -pruN 0.8.0-0.3/scrypt-1.2.0/scrypt_platform.h 0.8.20-1/scrypt-1.2.0/scrypt_platform.h
--- 0.8.0-0.3/scrypt-1.2.0/scrypt_platform.h	2015-07-05 10:02:58.000000000 +0000
+++ 0.8.20-1/scrypt-1.2.0/scrypt_platform.h	1970-01-01 00:00:00.000000000 +0000
@@ -1,12 +0,0 @@
-#ifndef _SCRYPT_PLATFORM_H_
-#define	_SCRYPT_PLATFORM_H_
-
-#if defined(CONFIG_H_FILE)
-#include CONFIG_H_FILE
-#elif defined(HAVE_CONFIG_H)
-#include "config.h"
-#else
-#error Need either CONFIG_H_FILE or HAVE_CONFIG_H defined.
-#endif
-
-#endif /* !_SCRYPT_PLATFORM_H_ */
diff -pruN 0.8.0-0.3/scrypt-1.2.1/config.h 0.8.20-1/scrypt-1.2.1/config.h
--- 0.8.0-0.3/scrypt-1.2.1/config.h	1970-01-01 00:00:00.000000000 +0000
+++ 0.8.20-1/scrypt-1.2.1/config.h	2022-02-21 10:55:27.000000000 +0000
@@ -0,0 +1,99 @@
+/* config.h.  Generated from config.h.in by configure.  */
+/* config.h.in.  Generated from configure.ac by autoheader.  */
+
+/* Define to 1 if you have the `clock_gettime' function. */
+/* #undef HAVE_CLOCK_GETTIME */
+
+/* Define to 1 if you have the declaration of `be64enc', and to 0 if you
+   don't. */
+#define HAVE_DECL_BE64ENC 0
+
+/* Define to 1 if you have the <err.h> header file. */
+#define HAVE_ERR_H 1
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the `rt' library (-lrt). */
+/* #undef HAVE_LIBRT */
+
+/* Define to 1 if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the `posix_memalign' function. */
+/* #undef HAVE_POSIX_MEMALIGN */
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if the system has the type `struct sysinfo'. */
+/* #undef HAVE_STRUCT_SYSINFO */
+
+/* Define to 1 if `mem_unit' is member of `struct sysinfo'. */
+/* #undef HAVE_STRUCT_SYSINFO_MEM_UNIT */
+
+/* Define to 1 if `totalram' is member of `struct sysinfo'. */
+/* #undef HAVE_STRUCT_SYSINFO_TOTALRAM */
+
+/* Define to 1 if the OS has a hw.usermem sysctl */
+/* #undef HAVE_SYSCTL_HW_USERMEM */
+
+/* Define to 1 if you have the `sysinfo' function. */
+/* #undef HAVE_SYSINFO */
+
+/* Define to 1 if you have the <sys/endian.h> header file. */
+/* #undef HAVE_SYS_ENDIAN_H */
+
+/* Define to 1 if you have the <sys/param.h> header file. */
+/* #define HAVE_SYS_PARAM_H */
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/sysinfo.h> header file. */
+/* #undef HAVE_SYS_SYSINFO_H */
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Name of package */
+#define PACKAGE "scrypt"
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT ""
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "scrypt"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "scrypt 1.2.1"
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "scrypt"
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "1.2.1"
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Version number of package */
+#define VERSION "1.2.1"
+
+/* Number of bits in a file offset, on hosts where this is settable. */
+/* #undef _FILE_OFFSET_BITS */
+
+/* Define for large files, on AIX-style hosts. */
+/* #undef _LARGE_FILES */
diff -pruN 0.8.0-0.3/scrypt-1.2.1/COPYRIGHT 0.8.20-1/scrypt-1.2.1/COPYRIGHT
--- 0.8.0-0.3/scrypt-1.2.1/COPYRIGHT	1970-01-01 00:00:00.000000000 +0000
+++ 0.8.20-1/scrypt-1.2.1/COPYRIGHT	2022-02-21 10:55:27.000000000 +0000
@@ -0,0 +1,27 @@
+The included code and documentation ("scrypt") is distributed under the
+following terms:
+
+Copyright 2005-2016 Colin Percival.  All rights reserved.
+Copyright 2005-2016 Tarsnap Backup Inc.  All rights reserved.
+Copyright 2014 Sean Kelly.  All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
diff -pruN 0.8.0-0.3/scrypt-1.2.1/FORMAT 0.8.20-1/scrypt-1.2.1/FORMAT
--- 0.8.0-0.3/scrypt-1.2.1/FORMAT	1970-01-01 00:00:00.000000000 +0000
+++ 0.8.20-1/scrypt-1.2.1/FORMAT	2022-02-21 10:55:27.000000000 +0000
@@ -0,0 +1,18 @@
+scrypt encrypted data format
+----------------------------
+
+offset	length
+0	6	"scrypt"
+6	1	scrypt data file version number (== 0)
+7	1	log2(N) (must be between 1 and 63 inclusive)
+8	4	r (big-endian integer; must satisfy r * p < 2^30)
+12	4	p (big-endian integer; must satisfy r * p < 2^30)
+16	32	salt
+48	16	first 16 bytes of SHA256(bytes 0 .. 47)
+64	32	HMAC-SHA256(bytes 0 .. 63)
+96	X	data xor AES256-CTR key stream generated with nonce == 0
+96+X	32	HMAC-SHA256(bytes 0 .. 96 + (X - 1))
+
+AES256-CTR is computed with a 256-bit AES key key_enc, and HMAC-SHA256 is
+computed with a 256-bit key key_hmac, where
+  scrypt(password, salt, N, r, p, 64) == [key_enc][key_hmac]
diff -pruN 0.8.0-0.3/scrypt-1.2.1/lib/crypto/crypto_scrypt.c 0.8.20-1/scrypt-1.2.1/lib/crypto/crypto_scrypt.c
--- 0.8.0-0.3/scrypt-1.2.1/lib/crypto/crypto_scrypt.c	1970-01-01 00:00:00.000000000 +0000
+++ 0.8.20-1/scrypt-1.2.1/lib/crypto/crypto_scrypt.c	2022-02-21 10:55:27.000000000 +0000
@@ -0,0 +1,255 @@
+/*-
+ * Copyright 2009 Colin Percival
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file was originally written by Colin Percival as part of the Tarsnap
+ * online backup system.
+ */
+#include "scrypt_platform.h"
+
+#include <sys/types.h>
+
+#ifndef _WIN32
+#include <sys/mman.h>
+#endif
+
+#include <errno.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "cpusupport.h"
+#include "sha256.h"
+#include "warnp.h"
+
+#include "crypto_scrypt_smix.h"
+#include "crypto_scrypt_smix_sse2.h"
+
+#include "crypto_scrypt.h"
+
+static void (*smix_func)(uint8_t *, size_t, uint64_t, void *, void *) = NULL;
+
+/**
+ * _crypto_scrypt(passwd, passwdlen, salt, saltlen, N, r, p, buf, buflen, smix):
+ * Perform the requested scrypt computation, using ${smix} as the smix routine.
+ */
+static int
+_crypto_scrypt(const uint8_t * passwd, size_t passwdlen,
+    const uint8_t * salt, size_t saltlen, uint64_t N, uint32_t _r, uint32_t _p,
+    uint8_t * buf, size_t buflen,
+    void (*smix)(uint8_t *, size_t, uint64_t, void *, void *))
+{
+	void * B0, * V0, * XY0;
+	uint8_t * B;
+	uint32_t * V;
+	uint32_t * XY;
+	size_t r = _r, p = _p;
+	uint32_t i;
+
+	/* Sanity-check parameters. */
+#if SIZE_MAX > UINT32_MAX
+	if (buflen > (((uint64_t)(1) << 32) - 1) * 32) {
+		errno = EFBIG;
+		goto err0;
+	}
+#endif
+	if ((uint64_t)(r) * (uint64_t)(p) >= (1 << 30)) {
+		errno = EFBIG;
+		goto err0;
+	}
+	if (((N & (N - 1)) != 0) || (N < 2)) {
+		errno = EINVAL;
+		goto err0;
+	}
+	if ((r > SIZE_MAX / 128 / p) ||
+#if SIZE_MAX / 256 <= UINT32_MAX
+	    (r > (SIZE_MAX - 64) / 256) ||
+#endif
+	    (N > SIZE_MAX / 128 / r)) {
+		errno = ENOMEM;
+		goto err0;
+	}
+
+	/* Allocate memory. */
+#ifdef HAVE_POSIX_MEMALIGN
+	if ((errno = posix_memalign(&B0, 64, 128 * r * p)) != 0)
+		goto err0;
+	B = (uint8_t *)(B0);
+	if ((errno = posix_memalign(&XY0, 64, 256 * r + 64)) != 0)
+		goto err1;
+	XY = (uint32_t *)(XY0);
+#if !defined(MAP_ANON) || !defined(HAVE_MMAP)
+	if ((errno = posix_memalign(&V0, 64, (size_t)(128 * r * N))) != 0)
+		goto err2;
+	V = (uint32_t *)(V0);
+#endif
+#else
+	if ((B0 = malloc(128 * r * p + 63)) == NULL)
+		goto err0;
+	B = (uint8_t *)(((uintptr_t)(B0) + 63) & ~ (uintptr_t)(63));
+	if ((XY0 = malloc(256 * r + 64 + 63)) == NULL)
+		goto err1;
+	XY = (uint32_t *)(((uintptr_t)(XY0) + 63) & ~ (uintptr_t)(63));
+#if !defined(MAP_ANON) || !defined(HAVE_MMAP)
+	if ((V0 = malloc(128 * r * N + 63)) == NULL)
+		goto err2;
+	V = (uint32_t *)(((uintptr_t)(V0) + 63) & ~ (uintptr_t)(63));
+#endif
+#endif
+#if defined(MAP_ANON) && defined(HAVE_MMAP)
+	if ((V0 = mmap(NULL, 128 * r * N, PROT_READ | PROT_WRITE,
+#ifdef MAP_NOCORE
+	    MAP_ANON | MAP_PRIVATE | MAP_NOCORE,
+#else
+	    MAP_ANON | MAP_PRIVATE,
+#endif
+	    -1, 0)) == MAP_FAILED)
+		goto err2;
+	V = (uint32_t *)(V0);
+#endif
+
+	/* 1: (B_0 ... B_{p-1}) <-- PBKDF2(P, S, 1, p * MFLen) */
+	PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, 1, B, p * 128 * r);
+
+	/* 2: for i = 0 to p - 1 do */
+	for (i = 0; i < p; i++) {
+		/* 3: B_i <-- MF(B_i, N) */
+		(smix)(&B[i * 128 * r], r, N, V, XY);
+	}
+
+	/* 5: DK <-- PBKDF2(P, B, 1, dkLen) */
+	PBKDF2_SHA256(passwd, passwdlen, B, p * 128 * r, 1, buf, buflen);
+
+	/* Free memory. */
+#if defined(MAP_ANON) && defined(HAVE_MMAP)
+	if (munmap(V0, 128 * r * N))
+		goto err2;
+#else
+	free(V0);
+#endif
+	free(XY0);
+	free(B0);
+
+	/* Success! */
+	return (0);
+
+err2:
+	free(XY0);
+err1:
+	free(B0);
+err0:
+	/* Failure! */
+	return (-1);
+}
+
+#define TESTLEN 64
+static struct scrypt_test {
+	const char * passwd;
+	const char * salt;
+	uint64_t N;
+	uint32_t r;
+	uint32_t p;
+	uint8_t result[TESTLEN];
+} testcase = {
+	"pleaseletmein",
+	"SodiumChloride",
+	16,
+	8,
+	1,
+	{
+		0x25, 0xa9, 0xfa, 0x20, 0x7f, 0x87, 0xca, 0x09,
+		0xa4, 0xef, 0x8b, 0x9f, 0x77, 0x7a, 0xca, 0x16,
+		0xbe, 0xb7, 0x84, 0xae, 0x18, 0x30, 0xbf, 0xbf,
+		0xd3, 0x83, 0x25, 0xaa, 0xbb, 0x93, 0x77, 0xdf,
+		0x1b, 0xa7, 0x84, 0xd7, 0x46, 0xea, 0x27, 0x3b,
+		0xf5, 0x16, 0xa4, 0x6f, 0xbf, 0xac, 0xf5, 0x11,
+		0xc5, 0xbe, 0xba, 0x4c, 0x4a, 0xb3, 0xac, 0xc7,
+		0xfa, 0x6f, 0x46, 0x0b, 0x6c, 0x0f, 0x47, 0x7b,
+	}
+};
+
+static int
+testsmix(void (*smix)(uint8_t *, size_t, uint64_t, void *, void *))
+{
+	uint8_t hbuf[TESTLEN];
+
+	/* Perform the computation. */
+	if (_crypto_scrypt(
+	    (const uint8_t *)testcase.passwd, strlen(testcase.passwd),
+	    (const uint8_t *)testcase.salt, strlen(testcase.salt),
+	    testcase.N, testcase.r, testcase.p, hbuf, TESTLEN, smix))
+		return (-1);
+
+	/* Does it match? */
+	return (memcmp(testcase.result, hbuf, TESTLEN));
+}
+
+static void
+selectsmix(void)
+{
+
+#ifdef CPUSUPPORT_X86_SSE2
+	/* If we're running on an SSE2-capable CPU, try that code. */
+	if (cpusupport_x86_sse2()) {
+		/* If SSE2ized smix works, use it. */
+		if (!testsmix(crypto_scrypt_smix_sse2)) {
+			smix_func = crypto_scrypt_smix_sse2;
+			return;
+		}
+		warn0("Disabling broken SSE2 scrypt support - please report bug!");
+	}
+#endif
+
+	/* If generic smix works, use it. */
+	if (!testsmix(crypto_scrypt_smix)) {
+		smix_func = crypto_scrypt_smix;
+		return;
+	}
+	warn0("Generic scrypt code is broken - please report bug!");
+
+	/* If we get here, something really bad happened. */
+	abort();
+}
+
+/**
+ * crypto_scrypt(passwd, passwdlen, salt, saltlen, N, r, p, buf, buflen):
+ * Compute scrypt(passwd[0 .. passwdlen - 1], salt[0 .. saltlen - 1], N, r,
+ * p, buflen) and write the result into buf.  The parameters r, p, and buflen
+ * must satisfy r * p < 2^30 and buflen <= (2^32 - 1) * 32.  The parameter N
+ * must be a power of 2 greater than 1.
+ *
+ * Return 0 on success; or -1 on error.
+ */
+int
+crypto_scrypt(const uint8_t * passwd, size_t passwdlen,
+    const uint8_t * salt, size_t saltlen, uint64_t N, uint32_t _r, uint32_t _p,
+    uint8_t * buf, size_t buflen)
+{
+
+	if (smix_func == NULL)
+		selectsmix();
+
+	return (_crypto_scrypt(passwd, passwdlen, salt, saltlen, N, _r, _p,
+	    buf, buflen, smix_func));
+}
diff -pruN 0.8.0-0.3/scrypt-1.2.1/lib/crypto/crypto_scrypt.h 0.8.20-1/scrypt-1.2.1/lib/crypto/crypto_scrypt.h
--- 0.8.0-0.3/scrypt-1.2.1/lib/crypto/crypto_scrypt.h	1970-01-01 00:00:00.000000000 +0000
+++ 0.8.20-1/scrypt-1.2.1/lib/crypto/crypto_scrypt.h	2022-02-21 10:55:27.000000000 +0000
@@ -0,0 +1,47 @@
+/*-
+ * Copyright 2009 Colin Percival
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file was originally written by Colin Percival as part of the Tarsnap
+ * online backup system.
+ */
+#ifndef _CRYPTO_SCRYPT_H_
+#define _CRYPTO_SCRYPT_H_
+
+#include <stdint.h>
+#include <unistd.h>
+
+/**
+ * crypto_scrypt(passwd, passwdlen, salt, saltlen, N, r, p, buf, buflen):
+ * Compute scrypt(passwd[0 .. passwdlen - 1], salt[0 .. saltlen - 1], N, r,
+ * p, buflen) and write the result into buf.  The parameters r, p, and buflen
+ * must satisfy r * p < 2^30 and buflen <= (2^32 - 1) * 32.  The parameter N
+ * must be a power of 2 greater than 1.
+ *
+ * Return 0 on success; or -1 on error.
+ */
+int crypto_scrypt(const uint8_t *, size_t, const uint8_t *, size_t, uint64_t,
+    uint32_t, uint32_t, uint8_t *, size_t);
+
+#endif /* !_CRYPTO_SCRYPT_H_ */
diff -pruN 0.8.0-0.3/scrypt-1.2.1/lib/crypto/crypto_scrypt-ref.c 0.8.20-1/scrypt-1.2.1/lib/crypto/crypto_scrypt-ref.c
--- 0.8.0-0.3/scrypt-1.2.1/lib/crypto/crypto_scrypt-ref.c	1970-01-01 00:00:00.000000000 +0000
+++ 0.8.20-1/scrypt-1.2.1/lib/crypto/crypto_scrypt-ref.c	2022-02-21 10:55:27.000000000 +0000
@@ -0,0 +1,285 @@
+/*-
+ * Copyright 2009 Colin Percival
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file was originally written by Colin Percival as part of the Tarsnap
+ * online backup system.
+ */
+#include "scrypt_platform.h"
+
+#include <errno.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "sha256.h"
+#include "sysendian.h"
+
+#include "crypto_scrypt.h"
+
+static void blkcpy(uint8_t *, uint8_t *, size_t);
+static void blkxor(uint8_t *, uint8_t *, size_t);
+static void salsa20_8(uint8_t[64]);
+static void blockmix_salsa8(uint8_t *, uint8_t *, size_t);
+static uint64_t integerify(uint8_t *, size_t);
+static void smix(uint8_t *, size_t, uint64_t, uint8_t *, uint8_t *);
+
+static void
+blkcpy(uint8_t * dest, uint8_t * src, size_t len)
+{
+	size_t i;
+
+	for (i = 0; i < len; i++)
+		dest[i] = src[i];
+}
+
+static void
+blkxor(uint8_t * dest, uint8_t * src, size_t len)
+{
+	size_t i;
+
+	for (i = 0; i < len; i++)
+		dest[i] ^= src[i];
+}
+
+/**
+ * salsa20_8(B):
+ * Apply the salsa20/8 core to the provided block.
+ */
+static void
+salsa20_8(uint8_t B[64])
+{
+	uint32_t B32[16];
+	uint32_t x[16];
+	size_t i;
+
+	/* Convert little-endian values in. */
+	for (i = 0; i < 16; i++)
+		B32[i] = le32dec(&B[i * 4]);
+
+	/* Compute x = doubleround^4(B32). */
+	for (i = 0; i < 16; i++)
+		x[i] = B32[i];
+	for (i = 0; i < 8; i += 2) {
+#define R(a,b) (((a) << (b)) | ((a) >> (32 - (b))))
+		/* Operate on columns. */
+		x[ 4] ^= R(x[ 0]+x[12], 7);  x[ 8] ^= R(x[ 4]+x[ 0], 9);
+		x[12] ^= R(x[ 8]+x[ 4],13);  x[ 0] ^= R(x[12]+x[ 8],18);
+
+		x[ 9] ^= R(x[ 5]+x[ 1], 7);  x[13] ^= R(x[ 9]+x[ 5], 9);
+		x[ 1] ^= R(x[13]+x[ 9],13);  x[ 5] ^= R(x[ 1]+x[13],18);
+
+		x[14] ^= R(x[10]+x[ 6], 7);  x[ 2] ^= R(x[14]+x[10], 9);
+		x[ 6] ^= R(x[ 2]+x[14],13);  x[10] ^= R(x[ 6]+x[ 2],18);
+
+		x[ 3] ^= R(x[15]+x[11], 7);  x[ 7] ^= R(x[ 3]+x[15], 9);
+		x[11] ^= R(x[ 7]+x[ 3],13);  x[15] ^= R(x[11]+x[ 7],18);
+
+		/* Operate on rows. */
+		x[ 1] ^= R(x[ 0]+x[ 3], 7);  x[ 2] ^= R(x[ 1]+x[ 0], 9);
+		x[ 3] ^= R(x[ 2]+x[ 1],13);  x[ 0] ^= R(x[ 3]+x[ 2],18);
+
+		x[ 6] ^= R(x[ 5]+x[ 4], 7);  x[ 7] ^= R(x[ 6]+x[ 5], 9);
+		x[ 4] ^= R(x[ 7]+x[ 6],13);  x[ 5] ^= R(x[ 4]+x[ 7],18);
+
+		x[11] ^= R(x[10]+x[ 9], 7);  x[ 8] ^= R(x[11]+x[10], 9);
+		x[ 9] ^= R(x[ 8]+x[11],13);  x[10] ^= R(x[ 9]+x[ 8],18);
+
+		x[12] ^= R(x[15]+x[14], 7);  x[13] ^= R(x[12]+x[15], 9);
+		x[14] ^= R(x[13]+x[12],13);  x[15] ^= R(x[14]+x[13],18);
+#undef R
+	}
+
+	/* Compute B32 = B32 + x. */
+	for (i = 0; i < 16; i++)
+		B32[i] += x[i];
+
+	/* Convert little-endian values out. */
+	for (i = 0; i < 16; i++)
+		le32enc(&B[4 * i], B32[i]);
+}
+
+/**
+ * blockmix_salsa8(B, Y, r):
+ * Compute B = BlockMix_{salsa20/8, r}(B).  The input B must be 128r bytes in
+ * length; the temporary space Y must also be the same size.
+ */
+static void
+blockmix_salsa8(uint8_t * B, uint8_t * Y, size_t r)
+{
+	uint8_t X[64];
+	size_t i;
+
+	/* 1: X <-- B_{2r - 1} */
+	blkcpy(X, &B[(2 * r - 1) * 64], 64);
+
+	/* 2: for i = 0 to 2r - 1 do */
+	for (i = 0; i < 2 * r; i++) {
+		/* 3: X <-- H(X \xor B_i) */
+		blkxor(X, &B[i * 64], 64);
+		salsa20_8(X);
+
+		/* 4: Y_i <-- X */
+		blkcpy(&Y[i * 64], X, 64);
+	}
+
+	/* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */
+	for (i = 0; i < r; i++)
+		blkcpy(&B[i * 64], &Y[(i * 2) * 64], 64);
+	for (i = 0; i < r; i++)
+		blkcpy(&B[(i + r) * 64], &Y[(i * 2 + 1) * 64], 64);
+}
+
+/**
+ * integerify(B, r):
+ * Return the result of parsing B_{2r-1} as a little-endian integer.
+ */
+static uint64_t
+integerify(uint8_t * B, size_t r)
+{
+	uint8_t * X = &B[(2 * r - 1) * 64];
+
+	return (le64dec(X));
+}
+
+/**
+ * smix(B, r, N, V, XY):
+ * Compute B = SMix_r(B, N).  The input B must be 128r bytes in length; the
+ * temporary storage V must be 128rN bytes in length; the temporary storage
+ * XY must be 256r bytes in length.  The value N must be a power of 2.
+ */
+static void
+smix(uint8_t * B, size_t r, uint64_t N, uint8_t * V, uint8_t * XY)
+{
+	uint8_t * X = XY;
+	uint8_t * Y = &XY[128 * r];
+	uint64_t i;
+	uint64_t j;
+
+	/* 1: X <-- B */
+	blkcpy(X, B, 128 * r);
+
+	/* 2: for i = 0 to N - 1 do */
+	for (i = 0; i < N; i++) {
+		/* 3: V_i <-- X */
+		blkcpy(&V[i * (128 * r)], X, 128 * r);
+
+		/* 4: X <-- H(X) */
+		blockmix_salsa8(X, Y, r);
+	}
+
+	/* 6: for i = 0 to N - 1 do */
+	for (i = 0; i < N; i++) {
+		/* 7: j <-- Integerify(X) mod N */
+		j = integerify(X, r) & (N - 1);
+
+		/* 8: X <-- H(X \xor V_j) */
+		blkxor(X, &V[j * (128 * r)], 128 * r);
+		blockmix_salsa8(X, Y, r);
+	}
+
+	/* 10: B' <-- X */
+	blkcpy(B, X, 128 * r);
+}
+
+/**
+ * crypto_scrypt(passwd, passwdlen, salt, saltlen, N, r, p, buf, buflen):
+ * Compute scrypt(passwd[0 .. passwdlen - 1], salt[0 .. saltlen - 1], N, r,
+ * p, buflen) and write the result into buf.  The parameters r, p, and buflen
+ * must satisfy r * p < 2^30 and buflen <= (2^32 - 1) * 32.  The parameter N
+ * must be a power of 2.
+ *
+ * Return 0 on success; or -1 on error.
+ */
+int
+crypto_scrypt(const uint8_t * passwd, size_t passwdlen,
+    const uint8_t * salt, size_t saltlen, uint64_t N, uint32_t _r, uint32_t _p,
+    uint8_t * buf, size_t buflen)
+{
+	uint8_t * B;
+	uint8_t * V;
+	uint8_t * XY;
+	size_t r = _r, p = _p;
+	uint32_t i;
+
+	/* Sanity-check parameters. */
+#if SIZE_MAX > UINT32_MAX
+	if (buflen > (((uint64_t)(1) << 32) - 1) * 32) {
+		errno = EFBIG;
+		goto err0;
+	}
+#endif
+	if ((uint64_t)(r) * (uint64_t)(p) >= (1 << 30)) {
+		errno = EFBIG;
+		goto err0;
+	}
+	if (((N & (N - 1)) != 0) || (N == 0)) {
+		errno = EINVAL;
+		goto err0;
+	}
+	if ((r > SIZE_MAX / 128 / p) ||
+#if SIZE_MAX / 256 <= UINT32_MAX
+	    (r > SIZE_MAX / 256) ||
+#endif
+	    (N > SIZE_MAX / 128 / r)) {
+		errno = ENOMEM;
+		goto err0;
+	}
+
+	/* Allocate memory. */
+	if ((B = malloc(128 * r * p)) == NULL)
+		goto err0;
+	if ((XY = malloc(256 * r)) == NULL)
+		goto err1;
+	if ((V = malloc(128 * r * N)) == NULL)
+		goto err2;
+
+	/* 1: (B_0 ... B_{p-1}) <-- PBKDF2(P, S, 1, p * MFLen) */
+	PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, 1, B, p * 128 * r);
+
+	/* 2: for i = 0 to p - 1 do */
+	for (i = 0; i < p; i++) {
+		/* 3: B_i <-- MF(B_i, N) */
+		smix(&B[i * 128 * r], r, N, V, XY);
+	}
+
+	/* 5: DK <-- PBKDF2(P, B, 1, dkLen) */
+	PBKDF2_SHA256(passwd, passwdlen, B, p * 128 * r, 1, buf, buflen);
+
+	/* Free memory. */
+	free(V);
+	free(XY);
+	free(B);
+
+	/* Success! */
+	return (0);
+
+err2:
+	free(XY);
+err1:
+	free(B);
+err0:
+	/* Failure! */
+	return (-1);
+}
diff -pruN 0.8.0-0.3/scrypt-1.2.1/lib/crypto/crypto_scrypt_smix.c 0.8.20-1/scrypt-1.2.1/lib/crypto/crypto_scrypt_smix.c
--- 0.8.0-0.3/scrypt-1.2.1/lib/crypto/crypto_scrypt_smix.c	1970-01-01 00:00:00.000000000 +0000
+++ 0.8.20-1/scrypt-1.2.1/lib/crypto/crypto_scrypt_smix.c	2022-02-21 10:55:27.000000000 +0000
@@ -0,0 +1,213 @@
+/*-
+ * Copyright 2009 Colin Percival
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file was originally written by Colin Percival as part of the Tarsnap
+ * online backup system.
+ */
+#include <stdint.h>
+
+#include "sysendian.h"
+
+#include "crypto_scrypt_smix.h"
+
+static void blkcpy(void *, const void *, size_t);
+static void blkxor(void *, const void *, size_t);
+static void salsa20_8(uint32_t[16]);
+static void blockmix_salsa8(const uint32_t *, uint32_t *, uint32_t *, size_t);
+static uint64_t integerify(const void *, size_t);
+
+static void
+blkcpy(void * dest, const void * src, size_t len)
+{
+	size_t * D = dest;
+	const size_t * S = src;
+	size_t L = len / sizeof(size_t);
+	size_t i;
+
+	for (i = 0; i < L; i++)
+		D[i] = S[i];
+}
+
+static void
+blkxor(void * dest, const void * src, size_t len)
+{
+	size_t * D = dest;
+	const size_t * S = src;
+	size_t L = len / sizeof(size_t);
+	size_t i;
+
+	for (i = 0; i < L; i++)
+		D[i] ^= S[i];
+}
+
+/**
+ * salsa20_8(B):
+ * Apply the salsa20/8 core to the provided block.
+ */
+static void
+salsa20_8(uint32_t B[16])
+{
+	uint32_t x[16];
+	size_t i;
+
+	blkcpy(x, B, 64);
+	for (i = 0; i < 8; i += 2) {
+#define R(a,b) (((a) << (b)) | ((a) >> (32 - (b))))
+		/* Operate on columns. */
+		x[ 4] ^= R(x[ 0]+x[12], 7);  x[ 8] ^= R(x[ 4]+x[ 0], 9);
+		x[12] ^= R(x[ 8]+x[ 4],13);  x[ 0] ^= R(x[12]+x[ 8],18);
+
+		x[ 9] ^= R(x[ 5]+x[ 1], 7);  x[13] ^= R(x[ 9]+x[ 5], 9);
+		x[ 1] ^= R(x[13]+x[ 9],13);  x[ 5] ^= R(x[ 1]+x[13],18);
+
+		x[14] ^= R(x[10]+x[ 6], 7);  x[ 2] ^= R(x[14]+x[10], 9);
+		x[ 6] ^= R(x[ 2]+x[14],13);  x[10] ^= R(x[ 6]+x[ 2],18);
+
+		x[ 3] ^= R(x[15]+x[11], 7);  x[ 7] ^= R(x[ 3]+x[15], 9);
+		x[11] ^= R(x[ 7]+x[ 3],13);  x[15] ^= R(x[11]+x[ 7],18);
+
+		/* Operate on rows. */
+		x[ 1] ^= R(x[ 0]+x[ 3], 7);  x[ 2] ^= R(x[ 1]+x[ 0], 9);
+		x[ 3] ^= R(x[ 2]+x[ 1],13);  x[ 0] ^= R(x[ 3]+x[ 2],18);
+
+		x[ 6] ^= R(x[ 5]+x[ 4], 7);  x[ 7] ^= R(x[ 6]+x[ 5], 9);
+		x[ 4] ^= R(x[ 7]+x[ 6],13);  x[ 5] ^= R(x[ 4]+x[ 7],18);
+
+		x[11] ^= R(x[10]+x[ 9], 7);  x[ 8] ^= R(x[11]+x[10], 9);
+		x[ 9] ^= R(x[ 8]+x[11],13);  x[10] ^= R(x[ 9]+x[ 8],18);
+
+		x[12] ^= R(x[15]+x[14], 7);  x[13] ^= R(x[12]+x[15], 9);
+		x[14] ^= R(x[13]+x[12],13);  x[15] ^= R(x[14]+x[13],18);
+#undef R
+	}
+	for (i = 0; i < 16; i++)
+		B[i] += x[i];
+}
+
+/**
+ * blockmix_salsa8(Bin, Bout, X, r):
+ * Compute Bout = BlockMix_{salsa20/8, r}(Bin).  The input Bin must be 128r
+ * bytes in length; the output Bout must also be the same size.  The
+ * temporary space X must be 64 bytes.
+ */
+static void
+blockmix_salsa8(const uint32_t * Bin, uint32_t * Bout, uint32_t * X, size_t r)
+{
+	size_t i;
+
+	/* 1: X <-- B_{2r - 1} */
+	blkcpy(X, &Bin[(2 * r - 1) * 16], 64);
+
+	/* 2: for i = 0 to 2r - 1 do */
+	for (i = 0; i < 2 * r; i += 2) {
+		/* 3: X <-- H(X \xor B_i) */
+		blkxor(X, &Bin[i * 16], 64);
+		salsa20_8(X);
+
+		/* 4: Y_i <-- X */
+		/* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */
+		blkcpy(&Bout[i * 8], X, 64);
+
+		/* 3: X <-- H(X \xor B_i) */
+		blkxor(X, &Bin[i * 16 + 16], 64);
+		salsa20_8(X);
+
+		/* 4: Y_i <-- X */
+		/* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */
+		blkcpy(&Bout[i * 8 + r * 16], X, 64);
+	}
+}
+
+/**
+ * integerify(B, r):
+ * Return the result of parsing B_{2r-1} as a little-endian integer.
+ */
+static uint64_t
+integerify(const void * B, size_t r)
+{
+	const uint32_t * X = (const void *)((uintptr_t)(B) + (2 * r - 1) * 64);
+
+	return (((uint64_t)(X[1]) << 32) + X[0]);
+}
+
+/**
+ * crypto_scrypt_smix(B, r, N, V, XY):
+ * Compute B = SMix_r(B, N).  The input B must be 128r bytes in length;
+ * the temporary storage V must be 128rN bytes in length; the temporary
+ * storage XY must be 256r + 64 bytes in length.  The value N must be a
+ * power of 2 greater than 1.  The arrays B, V, and XY must be aligned to a
+ * multiple of 64 bytes.
+ */
+void
+crypto_scrypt_smix(uint8_t * B, size_t r, uint64_t N, void * _V, void * XY)
+{
+	uint32_t * X = XY;
+	uint32_t * Y = (void *)((uint8_t *)(XY) + 128 * r);
+	uint32_t * Z = (void *)((uint8_t *)(XY) + 256 * r);
+	uint32_t * V = _V;
+	uint64_t i;
+	uint64_t j;
+	size_t k;
+
+	/* 1: X <-- B */
+	for (k = 0; k < 32 * r; k++)
+		X[k] = le32dec(&B[4 * k]);
+
+	/* 2: for i = 0 to N - 1 do */
+	for (i = 0; i < N; i += 2) {
+		/* 3: V_i <-- X */
+		blkcpy(&V[i * (32 * r)], X, 128 * r);
+
+		/* 4: X <-- H(X) */
+		blockmix_salsa8(X, Y, Z, r);
+
+		/* 3: V_i <-- X */
+		blkcpy(&V[(i + 1) * (32 * r)], Y, 128 * r);
+
+		/* 4: X <-- H(X) */
+		blockmix_salsa8(Y, X, Z, r);
+	}
+
+	/* 6: for i = 0 to N - 1 do */
+	for (i = 0; i < N; i += 2) {
+		/* 7: j <-- Integerify(X) mod N */
+		j = integerify(X, r) & (N - 1);
+
+		/* 8: X <-- H(X \xor V_j) */
+		blkxor(X, &V[j * (32 * r)], 128 * r);
+		blockmix_salsa8(X, Y, Z, r);
+
+		/* 7: j <-- Integerify(X) mod N */
+		j = integerify(Y, r) & (N - 1);
+
+		/* 8: X <-- H(X \xor V_j) */
+		blkxor(Y, &V[j * (32 * r)], 128 * r);
+		blockmix_salsa8(Y, X, Z, r);
+	}
+
+	/* 10: B' <-- X */
+	for (k = 0; k < 32 * r; k++)
+		le32enc(&B[4 * k], X[k]);
+}
diff -pruN 0.8.0-0.3/scrypt-1.2.1/lib/crypto/crypto_scrypt_smix.h 0.8.20-1/scrypt-1.2.1/lib/crypto/crypto_scrypt_smix.h
--- 0.8.0-0.3/scrypt-1.2.1/lib/crypto/crypto_scrypt_smix.h	1970-01-01 00:00:00.000000000 +0000
+++ 0.8.20-1/scrypt-1.2.1/lib/crypto/crypto_scrypt_smix.h	2022-02-21 10:55:27.000000000 +0000
@@ -0,0 +1,17 @@
+#ifndef _CRYPTO_SCRYPT_SMIX_H_
+#define _CRYPTO_SCRYPT_SMIX_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+/**
+ * crypto_scrypt_smix(B, r, N, V, XY):
+ * Compute B = SMix_r(B, N).  The input B must be 128r bytes in length;
+ * the temporary storage V must be 128rN bytes in length; the temporary
+ * storage XY must be 256r + 64 bytes in length.  The value N must be a
+ * power of 2 greater than 1.  The arrays B, V, and XY must be aligned to a
+ * multiple of 64 bytes.
+ */
+void crypto_scrypt_smix(uint8_t *, size_t, uint64_t, void *, void *);
+
+#endif /* !_CRYPTO_SCRYPT_SMIX_H_ */
diff -pruN 0.8.0-0.3/scrypt-1.2.1/lib/crypto/crypto_scrypt_smix_sse2.c 0.8.20-1/scrypt-1.2.1/lib/crypto/crypto_scrypt_smix_sse2.c
--- 0.8.0-0.3/scrypt-1.2.1/lib/crypto/crypto_scrypt_smix_sse2.c	1970-01-01 00:00:00.000000000 +0000
+++ 0.8.20-1/scrypt-1.2.1/lib/crypto/crypto_scrypt_smix_sse2.c	2022-02-21 10:55:27.000000000 +0000
@@ -0,0 +1,248 @@
+/*-
+ * Copyright 2009 Colin Percival
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file was originally written by Colin Percival as part of the Tarsnap
+ * online backup system.
+ */
+#include "cpusupport.h"
+#ifdef CPUSUPPORT_X86_SSE2
+
+#include <emmintrin.h>
+#include <stdint.h>
+
+#include "sysendian.h"
+
+#include "crypto_scrypt_smix_sse2.h"
+
+static void blkcpy(void *, const void *, size_t);
+static void blkxor(void *, const void *, size_t);
+static void salsa20_8(__m128i *);
+static void blockmix_salsa8(const __m128i *, __m128i *, __m128i *, size_t);
+static uint64_t integerify(const void *, size_t);
+
+static void
+blkcpy(void * dest, const void * src, size_t len)
+{
+	__m128i * D = dest;
+	const __m128i * S = src;
+	size_t L = len / 16;
+	size_t i;
+
+	for (i = 0; i < L; i++)
+		D[i] = S[i];
+}
+
+static void
+blkxor(void * dest, const void * src, size_t len)
+{
+	__m128i * D = dest;
+	const __m128i * S = src;
+	size_t L = len / 16;
+	size_t i;
+
+	for (i = 0; i < L; i++)
+		D[i] = _mm_xor_si128(D[i], S[i]);
+}
+
+/**
+ * salsa20_8(B):
+ * Apply the salsa20/8 core to the provided block.
+ */
+static void
+salsa20_8(__m128i B[4])
+{
+	__m128i X0, X1, X2, X3;
+	__m128i T;
+	size_t i;
+
+	X0 = B[0];
+	X1 = B[1];
+	X2 = B[2];
+	X3 = B[3];
+
+	for (i = 0; i < 8; i += 2) {
+		/* Operate on "columns". */
+		T = _mm_add_epi32(X0, X3);
+		X1 = _mm_xor_si128(X1, _mm_slli_epi32(T, 7));
+		X1 = _mm_xor_si128(X1, _mm_srli_epi32(T, 25));
+		T = _mm_add_epi32(X1, X0);
+		X2 = _mm_xor_si128(X2, _mm_slli_epi32(T, 9));
+		X2 = _mm_xor_si128(X2, _mm_srli_epi32(T, 23));
+		T = _mm_add_epi32(X2, X1);
+		X3 = _mm_xor_si128(X3, _mm_slli_epi32(T, 13));
+		X3 = _mm_xor_si128(X3, _mm_srli_epi32(T, 19));
+		T = _mm_add_epi32(X3, X2);
+		X0 = _mm_xor_si128(X0, _mm_slli_epi32(T, 18));
+		X0 = _mm_xor_si128(X0, _mm_srli_epi32(T, 14));
+
+		/* Rearrange data. */
+		X1 = _mm_shuffle_epi32(X1, 0x93);
+		X2 = _mm_shuffle_epi32(X2, 0x4E);
+		X3 = _mm_shuffle_epi32(X3, 0x39);
+
+		/* Operate on "rows". */
+		T = _mm_add_epi32(X0, X1);
+		X3 = _mm_xor_si128(X3, _mm_slli_epi32(T, 7));
+		X3 = _mm_xor_si128(X3, _mm_srli_epi32(T, 25));
+		T = _mm_add_epi32(X3, X0);
+		X2 = _mm_xor_si128(X2, _mm_slli_epi32(T, 9));
+		X2 = _mm_xor_si128(X2, _mm_srli_epi32(T, 23));
+		T = _mm_add_epi32(X2, X3);
+		X1 = _mm_xor_si128(X1, _mm_slli_epi32(T, 13));
+		X1 = _mm_xor_si128(X1, _mm_srli_epi32(T, 19));
+		T = _mm_add_epi32(X1, X2);
+		X0 = _mm_xor_si128(X0, _mm_slli_epi32(T, 18));
+		X0 = _mm_xor_si128(X0, _mm_srli_epi32(T, 14));
+
+		/* Rearrange data. */
+		X1 = _mm_shuffle_epi32(X1, 0x39);
+		X2 = _mm_shuffle_epi32(X2, 0x4E);
+		X3 = _mm_shuffle_epi32(X3, 0x93);
+	}
+
+	B[0] = _mm_add_epi32(B[0], X0);
+	B[1] = _mm_add_epi32(B[1], X1);
+	B[2] = _mm_add_epi32(B[2], X2);
+	B[3] = _mm_add_epi32(B[3], X3);
+}
+
+/**
+ * blockmix_salsa8(Bin, Bout, X, r):
+ * Compute Bout = BlockMix_{salsa20/8, r}(Bin).  The input Bin must be 128r
+ * bytes in length; the output Bout must also be the same size.  The
+ * temporary space X must be 64 bytes.
+ */
+static void
+blockmix_salsa8(const __m128i * Bin, __m128i * Bout, __m128i * X, size_t r)
+{
+	size_t i;
+
+	/* 1: X <-- B_{2r - 1} */
+	blkcpy(X, &Bin[8 * r - 4], 64);
+
+	/* 2: for i = 0 to 2r - 1 do */
+	for (i = 0; i < r; i++) {
+		/* 3: X <-- H(X \xor B_i) */
+		blkxor(X, &Bin[i * 8], 64);
+		salsa20_8(X);
+
+		/* 4: Y_i <-- X */
+		/* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */
+		blkcpy(&Bout[i * 4], X, 64);
+
+		/* 3: X <-- H(X \xor B_i) */
+		blkxor(X, &Bin[i * 8 + 4], 64);
+		salsa20_8(X);
+
+		/* 4: Y_i <-- X */
+		/* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */
+		blkcpy(&Bout[(r + i) * 4], X, 64);
+	}
+}
+
+/**
+ * integerify(B, r):
+ * Return the result of parsing B_{2r-1} as a little-endian integer.
+ * Note that B's layout is permuted compared to the generic implementation.
+ */
+static uint64_t
+integerify(const void * B, size_t r)
+{
+	const uint32_t * X = (const void *)((uintptr_t)(B) + (2 * r - 1) * 64);
+
+	return (((uint64_t)(X[13]) << 32) + X[0]);
+}
+
+/**
+ * crypto_scrypt_smix_sse2(B, r, N, V, XY):
+ * Compute B = SMix_r(B, N).  The input B must be 128r bytes in length;
+ * the temporary storage V must be 128rN bytes in length; the temporary
+ * storage XY must be 256r + 64 bytes in length.  The value N must be a
+ * power of 2 greater than 1.  The arrays B, V, and XY must be aligned to a
+ * multiple of 64 bytes.
+ *
+ * Use SSE2 instructions.
+ */
+void
+crypto_scrypt_smix_sse2(uint8_t * B, size_t r, uint64_t N, void * V, void * XY)
+{
+	__m128i * X = XY;
+	__m128i * Y = (void *)((uintptr_t)(XY) + 128 * r);
+	__m128i * Z = (void *)((uintptr_t)(XY) + 256 * r);
+	uint32_t * X32 = (void *)X;
+	uint64_t i, j;
+	size_t k;
+
+	/* 1: X <-- B */
+	for (k = 0; k < 2 * r; k++) {
+		for (i = 0; i < 16; i++) {
+			X32[k * 16 + i] =
+			    le32dec(&B[(k * 16 + (i * 5 % 16)) * 4]);
+		}
+	}
+
+	/* 2: for i = 0 to N - 1 do */
+	for (i = 0; i < N; i += 2) {
+		/* 3: V_i <-- X */
+		blkcpy((void *)((uintptr_t)(V) + i * 128 * r), X, 128 * r);
+
+		/* 4: X <-- H(X) */
+		blockmix_salsa8(X, Y, Z, r);
+
+		/* 3: V_i <-- X */
+		blkcpy((void *)((uintptr_t)(V) + (i + 1) * 128 * r),
+		    Y, 128 * r);
+
+		/* 4: X <-- H(X) */
+		blockmix_salsa8(Y, X, Z, r);
+	}
+
+	/* 6: for i = 0 to N - 1 do */
+	for (i = 0; i < N; i += 2) {
+		/* 7: j <-- Integerify(X) mod N */
+		j = integerify(X, r) & (N - 1);
+
+		/* 8: X <-- H(X \xor V_j) */
+		blkxor(X, (void *)((uintptr_t)(V) + j * 128 * r), 128 * r);
+		blockmix_salsa8(X, Y, Z, r);
+
+		/* 7: j <-- Integerify(X) mod N */
+		j = integerify(Y, r) & (N - 1);
+
+		/* 8: X <-- H(X \xor V_j) */
+		blkxor(Y, (void *)((uintptr_t)(V) + j * 128 * r), 128 * r);
+		blockmix_salsa8(Y, X, Z, r);
+	}
+
+	/* 10: B' <-- X */
+	for (k = 0; k < 2 * r; k++) {
+		for (i = 0; i < 16; i++) {
+			le32enc(&B[(k * 16 + (i * 5 % 16)) * 4],
+			    X32[k * 16 + i]);
+		}
+	}
+}
+
+#endif /* CPUSUPPORT_X86_SSE2 */
diff -pruN 0.8.0-0.3/scrypt-1.2.1/lib/crypto/crypto_scrypt_smix_sse2.h 0.8.20-1/scrypt-1.2.1/lib/crypto/crypto_scrypt_smix_sse2.h
--- 0.8.0-0.3/scrypt-1.2.1/lib/crypto/crypto_scrypt_smix_sse2.h	1970-01-01 00:00:00.000000000 +0000
+++ 0.8.20-1/scrypt-1.2.1/lib/crypto/crypto_scrypt_smix_sse2.h	2022-02-21 10:55:27.000000000 +0000
@@ -0,0 +1,19 @@
+#ifndef _CRYPTO_SCRYPT_SMIX_SSE2_H_
+#define _CRYPTO_SCRYPT_SMIX_SSE2_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+/**
+ * crypto_scrypt_smix_sse2(B, r, N, V, XY):
+ * Compute B = SMix_r(B, N).  The input B must be 128r bytes in length;
+ * the temporary storage V must be 128rN bytes in length; the temporary
+ * storage XY must be 256r + 64 bytes in length.  The value N must be a
+ * power of 2 greater than 1.  The arrays B, V, and XY must be aligned to a
+ * multiple of 64 bytes.
+ *
+ * Use SSE2 instructions.
+ */
+void crypto_scrypt_smix_sse2(uint8_t *, size_t, uint64_t, void *, void *);
+
+#endif /* !_CRYPTO_SCRYPT_SMIX_SSE2_H_ */
diff -pruN 0.8.0-0.3/scrypt-1.2.1/lib/README 0.8.20-1/scrypt-1.2.1/lib/README
--- 0.8.0-0.3/scrypt-1.2.1/lib/README	1970-01-01 00:00:00.000000000 +0000
+++ 0.8.20-1/scrypt-1.2.1/lib/README	2022-02-21 10:55:27.000000000 +0000
@@ -0,0 +1,6 @@
+The source code under this directory is taken from the client for the
+Tarsnap online backup system (and released under the 2-clause BSD license
+with permission of the author); keeping this code in sync with the Tarsnap
+code is highly desirable and explains why there is some functionality
+included here which is not actually used by the scrypt file encryption
+utility.
diff -pruN 0.8.0-0.3/scrypt-1.2.1/lib/scryptenc/scryptenc.c 0.8.20-1/scrypt-1.2.1/lib/scryptenc/scryptenc.c
--- 0.8.0-0.3/scrypt-1.2.1/lib/scryptenc/scryptenc.c	1970-01-01 00:00:00.000000000 +0000
+++ 0.8.20-1/scrypt-1.2.1/lib/scryptenc/scryptenc.c	2022-02-21 10:55:27.000000000 +0000
@@ -0,0 +1,609 @@
+/*-
+ * Copyright 2009 Colin Percival
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file was originally written by Colin Percival as part of the Tarsnap
+ * online backup system.
+ */
+#include "scrypt_platform.h"
+
+#include <assert.h>
+#include <inttypes.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "crypto_aes.h"
+#include "crypto_aesctr.h"
+#include "crypto_entropy.h"
+#include "humansize.h"
+#include "insecure_memzero.h"
+#include "sha256.h"
+#include "sysendian.h"
+
+#include "crypto_scrypt.h"
+#include "memlimit.h"
+#include "scryptenc_cpuperf.h"
+
+#include "scryptenc.h"
+
+#define ENCBLOCK 65536
+
+static int pickparams(size_t, double, double,
+    int *, uint32_t *, uint32_t *, int);
+static int checkparams(size_t, double, double, int, uint32_t, uint32_t, int,
+    int);
+
+static void
+display_params(int logN, uint32_t r, uint32_t p, size_t memlimit,
+    double opps, double maxtime)
+{
+	uint64_t N = (uint64_t)(1) << logN;
+	uint64_t mem_minimum = 128 * r * N;
+	double expected_seconds = 4 * N * p / opps;
+	char * human_memlimit = humansize(memlimit);
+	char * human_mem_minimum = humansize(mem_minimum);
+
+	fprintf(stderr, "Parameters used: N = %" PRIu64 "; r = %" PRIu32
+	    "; p = %" PRIu32 ";\n", N, r, p);
+	fprintf(stderr, "    This requires at least %s bytes of memory "
+	    "(%s available),\n", human_mem_minimum, human_memlimit);
+	fprintf(stderr, "    and will take approximately %.1f seconds "
+	    "(limit: %.1f seconds).\n", expected_seconds, maxtime);
+
+	free(human_memlimit);
+	free(human_mem_minimum);
+}
+
+static int
+pickparams(size_t maxmem, double maxmemfrac, double maxtime,
+    int * logN, uint32_t * r, uint32_t * p, int verbose)
+{
+	size_t memlimit;
+	double opps;
+	double opslimit;
+	double maxN, maxrp;
+	int rc;
+
+	/* Figure out how much memory to use. */
+	if (memtouse(maxmem, maxmemfrac, &memlimit))
+		return (1);
+
+	/* Figure out how fast the CPU is. */
+	if ((rc = scryptenc_cpuperf(&opps)) != 0)
+		return (rc);
+	opslimit = opps * maxtime;
+
+	/* Allow a minimum of 2^15 salsa20/8 cores. */
+	if (opslimit < 32768)
+		opslimit = 32768;
+
+	/* Fix r = 8 for now. */
+	*r = 8;
+
+	/*
+	 * The memory limit requires that 128Nr <= memlimit, while the CPU
+	 * limit requires that 4Nrp <= opslimit.  If opslimit < memlimit/32,
+	 * opslimit imposes the stronger limit on N.
+	 */
+#ifdef DEBUG
+	fprintf(stderr, "Requiring 128Nr <= %zu, 4Nrp <= %f\n",
+	    memlimit, opslimit);
+#endif
+	if (opslimit < (double)memlimit / 32) {
+		/* Set p = 1 and choose N based on the CPU limit. */
+		*p = 1;
+		maxN = opslimit / (*r * 4);
+		for (*logN = 1; *logN < 63; *logN += 1) {
+			if ((uint64_t)(1) << *logN > maxN / 2)
+				break;
+		}
+	} else {
+		/* Set N based on the memory limit. */
+		maxN = memlimit / (*r * 128);
+		for (*logN = 1; *logN < 63; *logN += 1) {
+			if ((uint64_t)(1) << *logN > maxN / 2)
+				break;
+		}
+
+		/* Choose p based on the CPU limit. */
+		maxrp = (opslimit / 4) / ((uint64_t)(1) << *logN);
+		if (maxrp > 0x3fffffff)
+			maxrp = 0x3fffffff;
+		*p = (uint32_t)(maxrp) / *r;
+	}
+
+	if (verbose)
+		display_params(*logN, *r, *p, memlimit, opps, maxtime);
+
+	/* Success! */
+	return (0);
+}
+
+static int
+checkparams(size_t maxmem, double maxmemfrac, double maxtime,
+    int logN, uint32_t r, uint32_t p, int verbose, int force)
+{
+	size_t memlimit;
+	double opps;
+	double opslimit;
+	uint64_t N;
+	int rc;
+
+	/* Sanity-check values. */
+	if ((logN < 1) || (logN > 63))
+		return (7);
+	if ((uint64_t)(r) * (uint64_t)(p) >= 0x40000000)
+		return (7);
+
+	/* Are we forcing decryption, regardless of resource limits? */
+	if (!force) {
+		/* Figure out the maximum amount of memory we can use. */
+		if (memtouse(maxmem, maxmemfrac, &memlimit))
+			return (1);
+
+		/* Figure out how fast the CPU is. */
+		if ((rc = scryptenc_cpuperf(&opps)) != 0)
+			return (rc);
+		opslimit = opps * maxtime;
+
+		/* Check limits. */
+		N = (uint64_t)(1) << logN;
+		if ((memlimit / N) / r < 128)
+			return (9);
+		if ((opslimit / N) / (r * p) < 4)
+			return (10);
+	} else {
+		/* We have no limit. */
+		memlimit = 0;
+		opps = 0;
+	}
+
+	if (verbose)
+		display_params(logN, r, p, memlimit, opps, maxtime);
+
+	/* Success! */
+	return (0);
+}
+
+static int
+scryptenc_setup(uint8_t header[96], uint8_t dk[64],
+    const uint8_t * passwd, size_t passwdlen,
+    size_t maxmem, double maxmemfrac, double maxtime, int verbose)
+{
+	uint8_t salt[32];
+	uint8_t hbuf[32];
+	int logN;
+	uint64_t N;
+	uint32_t r;
+	uint32_t p;
+	SHA256_CTX ctx;
+	uint8_t * key_hmac = &dk[32];
+	HMAC_SHA256_CTX hctx;
+	int rc;
+
+	/* Pick values for N, r, p. */
+	if ((rc = pickparams(maxmem, maxmemfrac, maxtime,
+	    &logN, &r, &p, verbose)) != 0)
+		return (rc);
+	N = (uint64_t)(1) << logN;
+
+	/* Sanity check. */
+	assert((logN > 0) && (logN < 256));
+
+	/* Get some salt. */
+	if (crypto_entropy_read(salt, 32))
+		return (4);
+
+	/* Generate the derived keys. */
+	if (crypto_scrypt(passwd, passwdlen, salt, 32, N, r, p, dk, 64))
+		return (3);
+
+	/* Construct the file header. */
+	memcpy(header, "scrypt", 6);
+	header[6] = 0;
+	header[7] = logN & 0xff;
+	be32enc(&header[8], r);
+	be32enc(&header[12], p);
+	memcpy(&header[16], salt, 32);
+
+	/* Add header checksum. */
+	SHA256_Init(&ctx);
+	SHA256_Update(&ctx, header, 48);
+	SHA256_Final(hbuf, &ctx);
+	memcpy(&header[48], hbuf, 16);
+
+	/* Add header signature (used for verifying password). */
+	HMAC_SHA256_Init(&hctx, key_hmac, 32);
+	HMAC_SHA256_Update(&hctx, header, 64);
+	HMAC_SHA256_Final(hbuf, &hctx);
+	memcpy(&header[64], hbuf, 32);
+
+	/* Success! */
+	return (0);
+}
+
+static int
+scryptdec_setup(const uint8_t header[96], uint8_t dk[64],
+    const uint8_t * passwd, size_t passwdlen,
+    size_t maxmem, double maxmemfrac, double maxtime, int verbose,
+    int force)
+{
+	uint8_t salt[32];
+	uint8_t hbuf[32];
+	int logN;
+	uint32_t r;
+	uint32_t p;
+	uint64_t N;
+	SHA256_CTX ctx;
+	uint8_t * key_hmac = &dk[32];
+	HMAC_SHA256_CTX hctx;
+	int rc;
+
+	/* Parse N, r, p, salt. */
+	logN = header[7];
+	r = be32dec(&header[8]);
+	p = be32dec(&header[12]);
+	memcpy(salt, &header[16], 32);
+
+	/* Verify header checksum. */
+	SHA256_Init(&ctx);
+	SHA256_Update(&ctx, header, 48);
+	SHA256_Final(hbuf, &ctx);
+	if (memcmp(&header[48], hbuf, 16))
+		return (7);
+
+	/*
+	 * Check whether the provided parameters are valid and whether the
+	 * key derivation function can be computed within the allowed memory
+	 * and CPU time, unless the user chose to disable this test.
+	 */
+	if ((rc = checkparams(maxmem, maxmemfrac, maxtime, logN, r, p,
+	    verbose, force)) != 0)
+		return (rc);
+
+	/* Compute the derived keys. */
+	N = (uint64_t)(1) << logN;
+	if (crypto_scrypt(passwd, passwdlen, salt, 32, N, r, p, dk, 64))
+		return (3);
+
+	/* Check header signature (i.e., verify password). */
+	HMAC_SHA256_Init(&hctx, key_hmac, 32);
+	HMAC_SHA256_Update(&hctx, header, 64);
+	HMAC_SHA256_Final(hbuf, &hctx);
+	if (memcmp(hbuf, &header[64], 32))
+		return (11);
+
+	/* Success! */
+	return (0);
+}
+
+/**
+ * scryptenc_buf(inbuf, inbuflen, outbuf, passwd, passwdlen,
+ *     maxmem, maxmemfrac, maxtime, verbose):
+ * Encrypt inbuflen bytes from inbuf, writing the resulting inbuflen + 128
+ * bytes to outbuf.
+ */
+int
+scryptenc_buf(const uint8_t * inbuf, size_t inbuflen, uint8_t * outbuf,
+    const uint8_t * passwd, size_t passwdlen,
+    size_t maxmem, double maxmemfrac, double maxtime, int verbose)
+{
+	uint8_t dk[64];
+	uint8_t hbuf[32];
+	uint8_t header[96];
+	uint8_t * key_enc = dk;
+	uint8_t * key_hmac = &dk[32];
+	int rc;
+	HMAC_SHA256_CTX hctx;
+	struct crypto_aes_key * key_enc_exp;
+	struct crypto_aesctr * AES;
+
+	/* Generate the header and derived key. */
+	if ((rc = scryptenc_setup(header, dk, passwd, passwdlen,
+	    maxmem, maxmemfrac, maxtime, verbose)) != 0)
+		return (rc);
+
+	/* Copy header into output buffer. */
+	memcpy(outbuf, header, 96);
+
+	/* Encrypt data. */
+	if ((key_enc_exp = crypto_aes_key_expand(key_enc, 32)) == NULL)
+		return (5);
+	if ((AES = crypto_aesctr_init(key_enc_exp, 0)) == NULL)
+		return (6);
+	crypto_aesctr_stream(AES, inbuf, &outbuf[96], inbuflen);
+	crypto_aesctr_free(AES);
+	crypto_aes_key_free(key_enc_exp);
+
+	/* Add signature. */
+	HMAC_SHA256_Init(&hctx, key_hmac, 32);
+	HMAC_SHA256_Update(&hctx, outbuf, 96 + inbuflen);
+	HMAC_SHA256_Final(hbuf, &hctx);
+	memcpy(&outbuf[96 + inbuflen], hbuf, 32);
+
+	/* Zero sensitive data. */
+	insecure_memzero(dk, 64);
+
+	/* Success! */
+	return (0);
+}
+
+/**
+ * scryptdec_buf(inbuf, inbuflen, outbuf, outlen, passwd, passwdlen,
+ *     maxmem, maxmemfrac, maxtime, verbose, force):
+ * Decrypt inbuflen bytes from inbuf, writing the result into outbuf and the
+ * decrypted data length to outlen.  The allocated length of outbuf must
+ * be at least inbuflen.  If ${force} is 1, do not check whether
+ * decryption will exceed the estimated available memory or time.
+ */
+int
+scryptdec_buf(const uint8_t * inbuf, size_t inbuflen, uint8_t * outbuf,
+    size_t * outlen, const uint8_t * passwd, size_t passwdlen,
+    size_t maxmem, double maxmemfrac, double maxtime, int verbose,
+    int force)
+{
+	uint8_t hbuf[32];
+	uint8_t dk[64];
+	uint8_t * key_enc = dk;
+	uint8_t * key_hmac = &dk[32];
+	int rc;
+	HMAC_SHA256_CTX hctx;
+	struct crypto_aes_key * key_enc_exp;
+	struct crypto_aesctr * AES;
+
+	/*
+	 * All versions of the scrypt format will start with "scrypt" and
+	 * have at least 7 bytes of header.
+	 */
+	if ((inbuflen < 7) || (memcmp(inbuf, "scrypt", 6) != 0))
+		return (7);
+
+	/* Check the format. */
+	if (inbuf[6] != 0)
+		return (8);
+
+	/* We must have at least 128 bytes. */
+	if (inbuflen < 128)
+		return (7);
+
+	/* Parse the header and generate derived keys. */
+	if ((rc = scryptdec_setup(inbuf, dk, passwd, passwdlen,
+	    maxmem, maxmemfrac, maxtime, verbose, force)) != 0)
+		return (rc);
+
+	/* Decrypt data. */
+	if ((key_enc_exp = crypto_aes_key_expand(key_enc, 32)) == NULL)
+		return (5);
+	if ((AES = crypto_aesctr_init(key_enc_exp, 0)) == NULL)
+		return (6);
+	crypto_aesctr_stream(AES, &inbuf[96], outbuf, inbuflen - 128);
+	crypto_aesctr_free(AES);
+	crypto_aes_key_free(key_enc_exp);
+	*outlen = inbuflen - 128;
+
+	/* Verify signature. */
+	HMAC_SHA256_Init(&hctx, key_hmac, 32);
+	HMAC_SHA256_Update(&hctx, inbuf, inbuflen - 32);
+	HMAC_SHA256_Final(hbuf, &hctx);
+	if (memcmp(hbuf, &inbuf[inbuflen - 32], 32))
+		return (7);
+
+	/* Zero sensitive data. */
+	insecure_memzero(dk, 64);
+
+	/* Success! */
+	return (0);
+}
+
+/**
+ * scryptenc_file(infile, outfile, passwd, passwdlen,
+ *     maxmem, maxmemfrac, maxtime, verbose):
+ * Read a stream from infile and encrypt it, writing the resulting stream to
+ * outfile.
+ */
+int
+scryptenc_file(FILE * infile, FILE * outfile,
+    const uint8_t * passwd, size_t passwdlen,
+    size_t maxmem, double maxmemfrac, double maxtime, int verbose)
+{
+	uint8_t buf[ENCBLOCK];
+	uint8_t dk[64];
+	uint8_t hbuf[32];
+	uint8_t header[96];
+	uint8_t * key_enc = dk;
+	uint8_t * key_hmac = &dk[32];
+	size_t readlen;
+	HMAC_SHA256_CTX hctx;
+	struct crypto_aes_key * key_enc_exp;
+	struct crypto_aesctr * AES;
+	int rc;
+
+	/* Generate the header and derived key. */
+	if ((rc = scryptenc_setup(header, dk, passwd, passwdlen,
+	    maxmem, maxmemfrac, maxtime, verbose)) != 0)
+		return (rc);
+
+	/* Hash and write the header. */
+	HMAC_SHA256_Init(&hctx, key_hmac, 32);
+	HMAC_SHA256_Update(&hctx, header, 96);
+	if (fwrite(header, 96, 1, outfile) != 1)
+		return (12);
+
+	/*
+	 * Read blocks of data, encrypt them, and write them out; hash the
+	 * data as it is produced.
+	 */
+	if ((key_enc_exp = crypto_aes_key_expand(key_enc, 32)) == NULL)
+		return (5);
+	if ((AES = crypto_aesctr_init(key_enc_exp, 0)) == NULL)
+		return (6);
+	do {
+		if ((readlen = fread(buf, 1, ENCBLOCK, infile)) == 0)
+			break;
+		crypto_aesctr_stream(AES, buf, buf, readlen);
+		HMAC_SHA256_Update(&hctx, buf, readlen);
+		if (fwrite(buf, 1, readlen, outfile) < readlen) {
+			crypto_aesctr_free(AES);
+			return (12);
+		}
+	} while (1);
+	crypto_aesctr_free(AES);
+	crypto_aes_key_free(key_enc_exp);
+
+	/* Did we exit the loop due to a read error? */
+	if (ferror(infile))
+		return (13);
+
+	/* Compute the final HMAC and output it. */
+	HMAC_SHA256_Final(hbuf, &hctx);
+	if (fwrite(hbuf, 32, 1, outfile) != 1)
+		return (12);
+
+	/* Zero sensitive data. */
+	insecure_memzero(dk, 64);
+
+	/* Success! */
+	return (0);
+}
+
+/**
+ * scryptdec_file(infile, outfile, passwd, passwdlen,
+ *     maxmem, maxmemfrac, maxtime, verbose, force):
+ * Read a stream from infile and decrypt it, writing the resulting stream to
+ * outfile.  If ${force} is 1, do not check whether decryption
+ * will exceed the estimated available memory or time.
+ */
+int
+scryptdec_file(FILE * infile, FILE * outfile,
+    const uint8_t * passwd, size_t passwdlen,
+    size_t maxmem, double maxmemfrac, double maxtime, int verbose,
+    int force)
+{
+	uint8_t buf[ENCBLOCK + 32];
+	uint8_t header[96];
+	uint8_t hbuf[32];
+	uint8_t dk[64];
+	uint8_t * key_enc = dk;
+	uint8_t * key_hmac = &dk[32];
+	size_t buflen = 0;
+	size_t readlen;
+	HMAC_SHA256_CTX hctx;
+	struct crypto_aes_key * key_enc_exp;
+	struct crypto_aesctr * AES;
+	int rc;
+
+	/*
+	 * Read the first 7 bytes of the file; all future versions of scrypt
+	 * are guaranteed to have at least 7 bytes of header.
+	 */
+	if (fread(header, 7, 1, infile) < 1) {
+		if (ferror(infile))
+			return (13);
+		else
+			return (7);
+	}
+
+	/* Do we have the right magic? */
+	if (memcmp(header, "scrypt", 6))
+		return (7);
+	if (header[6] != 0)
+		return (8);
+
+	/*
+	 * Read another 89 bytes of the file; version 0 of the scrypt file
+	 * format has a 96-byte header.
+	 */
+	if (fread(&header[7], 89, 1, infile) < 1) {
+		if (ferror(infile))
+			return (13);
+		else
+			return (7);
+	}
+
+	/* Parse the header and generate derived keys. */
+	if ((rc = scryptdec_setup(header, dk, passwd, passwdlen,
+	    maxmem, maxmemfrac, maxtime, verbose, force)) != 0)
+		return (rc);
+
+	/* Start hashing with the header. */
+	HMAC_SHA256_Init(&hctx, key_hmac, 32);
+	HMAC_SHA256_Update(&hctx, header, 96);
+
+	/*
+	 * We don't know how long the encrypted data block is (we can't know,
+	 * since data can be streamed into 'scrypt enc') so we need to read
+	 * data and decrypt all of it except the final 32 bytes, then check
+	 * if that final 32 bytes is the correct signature.
+	 */
+	if ((key_enc_exp = crypto_aes_key_expand(key_enc, 32)) == NULL)
+		return (5);
+	if ((AES = crypto_aesctr_init(key_enc_exp, 0)) == NULL)
+		return (6);
+	do {
+		/* Read data until we have more than 32 bytes of it. */
+		if ((readlen = fread(&buf[buflen], 1,
+		    ENCBLOCK + 32 - buflen, infile)) == 0)
+			break;
+		buflen += readlen;
+		if (buflen <= 32)
+			continue;
+
+		/*
+		 * Decrypt, hash, and output everything except the last 32
+		 * bytes out of what we have in our buffer.
+		 */
+		HMAC_SHA256_Update(&hctx, buf, buflen - 32);
+		crypto_aesctr_stream(AES, buf, buf, buflen - 32);
+		if (fwrite(buf, 1, buflen - 32, outfile) < buflen - 32) {
+			crypto_aesctr_free(AES);
+			return (12);
+		}
+
+		/* Move the last 32 bytes to the start of the buffer. */
+		memmove(buf, &buf[buflen - 32], 32);
+		buflen = 32;
+	} while (1);
+	crypto_aesctr_free(AES);
+	crypto_aes_key_free(key_enc_exp);
+
+	/* Did we exit the loop due to a read error? */
+	if (ferror(infile))
+		return (13);
+
+	/* Did we read enough data that we *might* have a valid signature? */
+	if (buflen < 32)
+		return (7);
+
+	/* Verify signature. */
+	HMAC_SHA256_Final(hbuf, &hctx);
+	if (memcmp(hbuf, buf, 32))
+		return (7);
+
+	/* Zero sensitive data. */
+	insecure_memzero(dk, 64);
+
+	return (0);
+}
diff -pruN 0.8.0-0.3/scrypt-1.2.1/lib/scryptenc/scryptenc_cpuperf.c 0.8.20-1/scrypt-1.2.1/lib/scryptenc/scryptenc_cpuperf.c
--- 0.8.0-0.3/scrypt-1.2.1/lib/scryptenc/scryptenc_cpuperf.c	1970-01-01 00:00:00.000000000 +0000
+++ 0.8.20-1/scrypt-1.2.1/lib/scryptenc/scryptenc_cpuperf.c	2022-02-21 10:55:27.000000000 +0000
@@ -0,0 +1,185 @@
+/*-
+ * Copyright 2009 Colin Percival
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file was originally written by Colin Percival as part of the Tarsnap
+ * online backup system.
+ */
+#include "scrypt_platform.h"
+
+#include <sys/time.h>
+
+#include <stdint.h>
+#include <stdio.h>
+#include <time.h>
+
+#include "crypto_scrypt.h"
+
+#include "scryptenc_cpuperf.h"
+
+#ifdef HAVE_CLOCK_GETTIME
+
+static clockid_t clocktouse;
+
+static int
+getclockres(double * resd)
+{
+	struct timespec res;
+
+	/*
+	 * Try clocks in order of preference until we find one which works.
+	 * (We assume that if clock_getres works, clock_gettime will, too.)
+	 * The use of if/else/if/else/if/else rather than if/elif/elif/else
+	 * is ugly but legal, and allows us to #ifdef things appropriately.
+	 */
+#ifdef CLOCK_VIRTUAL
+	if (clock_getres(CLOCK_VIRTUAL, &res) == 0)
+		clocktouse = CLOCK_VIRTUAL;
+	else
+#endif
+#ifdef CLOCK_MONOTONIC
+	if (clock_getres(CLOCK_MONOTONIC, &res) == 0)
+		clocktouse = CLOCK_MONOTONIC;
+	else
+#endif
+	if (clock_getres(CLOCK_REALTIME, &res) == 0)
+		clocktouse = CLOCK_REALTIME;
+	else
+		return (-1);
+
+	/* Convert clock resolution to a double. */
+	*resd = res.tv_sec + res.tv_nsec * 0.000000001;
+
+	return (0);
+}
+
+static int
+getclocktime(struct timespec * ts)
+{
+
+	if (clock_gettime(clocktouse, ts))
+		return (-1);
+
+	return (0);
+}
+
+#else
+static int
+getclockres(double * resd)
+{
+
+	*resd = 1.0 / CLOCKS_PER_SEC;
+
+	return (0);
+}
+
+static int
+getclocktime(struct timespec * ts)
+{
+	struct timeval tv;
+
+	if (gettimeofday(&tv, NULL))
+		return (-1);
+	ts->tv_sec = tv.tv_sec;
+	ts->tv_nsec = tv.tv_usec * 1000;
+
+	return (0);
+}
+#endif
+
+static int
+getclockdiff(struct timespec * st, double * diffd)
+{
+	struct timespec en;
+
+	if (getclocktime(&en))
+		return (1);
+	*diffd = (en.tv_nsec - st->tv_nsec) * 0.000000001 +
+	    (en.tv_sec - st->tv_sec);
+
+	return (0);
+}
+
+/**
+ * scryptenc_cpuperf(opps):
+ * Estimate the number of salsa20/8 cores which can be executed per second,
+ * and return the value via opps.
+ */
+int
+scryptenc_cpuperf(double * opps)
+{
+	struct timespec st;
+	double resd, diffd;
+	uint64_t i = 0;
+
+	/* Get the clock resolution. */
+	if (getclockres(&resd))
+		return (2);
+
+#ifdef DEBUG
+	fprintf(stderr, "Clock resolution is %f\n", resd);
+#endif
+
+	/* Loop until the clock ticks. */
+	if (getclocktime(&st))
+		return (2);
+	do {
+		/* Do an scrypt. */
+		if (crypto_scrypt(NULL, 0, NULL, 0, 16, 1, 1, NULL, 0))
+			return (3);
+
+		/* Has the clock ticked? */
+		if (getclockdiff(&st, &diffd))
+			return (2);
+		if (diffd > 0)
+			break;
+	} while (1);
+
+	/* Count how many scrypts we can do before the next tick. */
+	if (getclocktime(&st))
+		return (2);
+	do {
+		/* Do an scrypt. */
+		if (crypto_scrypt(NULL, 0, NULL, 0, 128, 1, 1, NULL, 0))
+			return (3);
+
+		/* We invoked the salsa20/8 core 512 times. */
+		i += 512;
+
+		/* Check if we have looped for long enough. */
+		if (getclockdiff(&st, &diffd))
+			return (2);
+		if (diffd > resd)
+			break;
+	} while (1);
+
+#ifdef DEBUG
+	fprintf(stderr, "%ju salsa20/8 cores performed in %f seconds\n",
+	    (uintmax_t)i, diffd);
+#endif
+
+	/* We can do approximately i salsa20/8 cores per diffd seconds. */
+	*opps = i / diffd;
+	return (0);
+}
diff -pruN 0.8.0-0.3/scrypt-1.2.1/lib/scryptenc/scryptenc_cpuperf.h 0.8.20-1/scrypt-1.2.1/lib/scryptenc/scryptenc_cpuperf.h
--- 0.8.0-0.3/scrypt-1.2.1/lib/scryptenc/scryptenc_cpuperf.h	1970-01-01 00:00:00.000000000 +0000
+++ 0.8.20-1/scrypt-1.2.1/lib/scryptenc/scryptenc_cpuperf.h	2022-02-21 10:55:27.000000000 +0000
@@ -0,0 +1,39 @@
+/*-
+ * Copyright 2009 Colin Percival
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file was originally written by Colin Percival as part of the Tarsnap
+ * online backup system.
+ */
+#ifndef _SCRYPTENC_CPUPERF_H_
+#define _SCRYPTENC_CPUPERF_H_
+
+/**
+ * scryptenc_cpuperf(opps):
+ * Estimate the number of salsa20/8 cores which can be executed per second,
+ * and return the value via opps.
+ */
+int scryptenc_cpuperf(double *);
+
+#endif /* !_SCRYPTENC_CPUPERF_H_ */
diff -pruN 0.8.0-0.3/scrypt-1.2.1/lib/scryptenc/scryptenc.h 0.8.20-1/scrypt-1.2.1/lib/scryptenc/scryptenc.h
--- 0.8.0-0.3/scrypt-1.2.1/lib/scryptenc/scryptenc.h	1970-01-01 00:00:00.000000000 +0000
+++ 0.8.20-1/scrypt-1.2.1/lib/scryptenc/scryptenc.h	2022-02-21 10:55:27.000000000 +0000
@@ -0,0 +1,122 @@
+/*-
+ * Copyright 2009 Colin Percival
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file was originally written by Colin Percival as part of the Tarsnap
+ * online backup system.
+ */
+#ifndef _SCRYPTENC_H_
+#define _SCRYPTENC_H_
+
+#include <stdint.h>
+#include <stdio.h>
+
+/**
+ * NOTE: This file provides prototypes for routines which encrypt/decrypt data
+ * using a key derived from a password by using the scrypt key derivation
+ * function.  If you are just trying to "hash" a password for user logins,
+ * this is not the code you are looking for.  You want to use the crypto_scrypt
+ * function directly.
+ */
+
+/**
+ * The parameters maxmem, maxmemfrac, and maxtime used by all of these
+ * functions are defined as follows:
+ * maxmem - maximum number of bytes of storage to use for V array (which is
+ *     by far the largest consumer of memory).  If this value is set to 0, no
+ *     maximum will be enforced; any other value less than 1 MiB will be
+ *     treated as 1 MiB.
+ * maxmemfrac - maximum fraction of available storage to use for the V array,
+ *     where "available storage" is defined as the minimum out of the
+ *     RLIMIT_AS, RLIMIT_DATA. and RLIMIT_RSS resource limits (if any are
+ *     set).  If this value is set to 0 or more than 0.5 it will be treated
+ *     as 0.5; and this value will never cause a limit of less than 1 MiB to
+ *     be enforced.
+ * maxtime - maximum amount of CPU time to spend computing the derived keys,
+ *     in seconds.  This limit is only approximately enforced; the CPU
+ *     performance is estimated and parameter limits are chosen accordingly.
+ * For the encryption functions, the parameters to the scrypt key derivation
+ * function are chosen to make the key as strong as possible subject to the
+ * specified limits; for the decryption functions, the parameters used are
+ * compared to the computed limits and an error is returned if decrypting
+ * the data would take too much memory or CPU time.
+ */
+/**
+ * Return codes from scrypt(enc|dec)_(buf|file):
+ * 0	success
+ * 1	getrlimit or sysctl(hw.usermem) failed
+ * 2	clock_getres or clock_gettime failed
+ * 3	error computing derived key
+ * 4	could not read salt from /dev/urandom
+ * 5	error in OpenSSL
+ * 6	malloc failed
+ * 7	data is not a valid scrypt-encrypted block
+ * 8	unrecognized scrypt format
+ * 9	decrypting file would take too much memory
+ * 10	decrypting file would take too long
+ * 11	password is incorrect
+ * 12	error writing output file
+ * 13	error reading input file
+ */
+
+/**
+ * scryptenc_buf(inbuf, inbuflen, outbuf, passwd, passwdlen,
+ *     maxmem, maxmemfrac, maxtime, verbose):
+ * Encrypt inbuflen bytes from inbuf, writing the resulting inbuflen + 128
+ * bytes to outbuf.
+ */
+int scryptenc_buf(const uint8_t *, size_t, uint8_t *,
+    const uint8_t *, size_t, size_t, double, double, int);
+
+/**
+ * scryptdec_buf(inbuf, inbuflen, outbuf, outlen, passwd, passwdlen,
+ *     maxmem, maxmemfrac, maxtime, verbose, force):
+ * Decrypt inbuflen bytes from inbuf, writing the result into outbuf and the
+ * decrypted data length to outlen.  The allocated length of outbuf must
+ * be at least inbuflen.  If ${force} is 1, do not check whether
+ * decryption will exceed the estimated available memory or time.
+ */
+int scryptdec_buf(const uint8_t *, size_t, uint8_t *, size_t *,
+    const uint8_t *, size_t, size_t, double, double, int, int);
+
+/**
+ * scryptenc_file(infile, outfile, passwd, passwdlen,
+ *     maxmem, maxmemfrac, maxtime, verbose):
+ * Read a stream from infile and encrypt it, writing the resulting stream to
+ * outfile.
+ */
+int scryptenc_file(FILE *, FILE *, const uint8_t *, size_t,
+    size_t, double, double, int);
+
+/**
+ * scryptdec_file(infile, outfile, passwd, passwdlen,
+ *     maxmem, maxmemfrac, maxtime, verbose, force):
+ * Read a stream from infile and decrypt it, writing the resulting stream to
+ * outfile.  If ${force} is 1, do not check whether decryption
+ * will exceed the estimated available memory or time.
+ */
+int scryptdec_file(FILE *, FILE *, const uint8_t *, size_t,
+    size_t, double, double, int, int);
+
+#endif /* !_SCRYPTENC_H_ */
diff -pruN 0.8.0-0.3/scrypt-1.2.1/lib/util/memlimit.c 0.8.20-1/scrypt-1.2.1/lib/util/memlimit.c
--- 0.8.0-0.3/scrypt-1.2.1/lib/util/memlimit.c	1970-01-01 00:00:00.000000000 +0000
+++ 0.8.20-1/scrypt-1.2.1/lib/util/memlimit.c	2022-02-21 10:55:27.000000000 +0000
@@ -0,0 +1,363 @@
+/*-
+ * Copyright 2009 Colin Percival
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file was originally written by Colin Percival as part of the Tarsnap
+ * online backup system.
+ */
+
+/* We use non-POSIX functionality in this file. */
+#undef _POSIX_C_SOURCE
+
+#include "scrypt_platform.h"
+
+#include <sys/types.h>
+
+#ifndef _WIN32
+#include <sys/resource.h>
+#else
+#define _WIN32_WINNT 0x0502
+#include <Windows.h>
+#include <tchar.h>
+#endif
+
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+#ifdef HAVE_SYS_SYSCTL_H
+#include <sys/sysctl.h>
+#endif
+#ifdef HAVE_SYS_SYSINFO_H
+#include <sys/sysinfo.h>
+#endif
+
+#include <errno.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+
+#ifdef DEBUG
+#include <stdio.h>
+#endif
+
+#include "memlimit.h"
+
+/* If we don't have CTL_HW, we can't use HW_USERMEM. */
+#ifndef CTL_HW
+#undef HW_USERMEM
+#endif
+
+#ifdef CTL_HW
+static int
+memlimit_sysctl_hw(size_t * memlimit, int mibleaf)
+{
+	int mib[2];
+	uint8_t sysctlbuf[8];
+	size_t sysctlbuflen = 8;
+	uint64_t sysctlval;
+
+	/* Ask the kernel how much RAM we have. */
+	mib[0] = CTL_HW;
+	mib[1] = mibleaf;
+	if (sysctl(mib, 2, sysctlbuf, &sysctlbuflen, NULL, 0))
+		return (1);
+
+	/*
+	 * If we read 8 bytes out, assume this is a system-endian uint64_t.
+	 * If we only read 4 bytes out, the OS is trying to give us a
+	 * uint32_t answer -- but given how many systems now have 4GB+ of RAM,
+	 * it's probably truncating, and we really can't trust the value we
+	 * have returned to us.
+	 */
+	if (sysctlbuflen == sizeof(uint64_t))
+		memcpy(&sysctlval, sysctlbuf, sizeof(uint64_t));
+	else if (sysctlbuflen == sizeof(uint32_t))
+		sysctlval = SIZE_MAX;
+	else
+		return (1);
+
+	/* Return the sysctl value, but clamp to SIZE_MAX if necessary. */
+#if UINT64_MAX > SIZE_MAX
+	if (sysctlval > SIZE_MAX)
+		*memlimit = SIZE_MAX;
+	else
+		*memlimit = (size_t)sysctlval;
+#else
+	*memlimit = sysctlval;
+#endif
+
+	/* Success! */
+	return (0);
+}
+#endif
+
+/* If we don't HAVE_STRUCT_SYSINFO, we can't use sysinfo. */
+#ifndef HAVE_STRUCT_SYSINFO
+#undef HAVE_SYSINFO
+#endif
+
+/* If we don't HAVE_STRUCT_SYSINFO_TOTALRAM, we can't use sysinfo. */
+#ifndef HAVE_STRUCT_SYSINFO_TOTALRAM
+#undef HAVE_SYSINFO
+#endif
+
+#ifdef HAVE_SYSINFO
+static int
+memlimit_sysinfo(size_t * memlimit)
+{
+	struct sysinfo info;
+	uint64_t totalmem;
+
+	/* Get information from the kernel. */
+	if (sysinfo(&info))
+		return (1);
+	totalmem = info.totalram;
+
+	/* If we're on a modern kernel, adjust based on mem_unit. */
+#ifdef HAVE_STRUCT_SYSINFO_MEM_UNIT
+	totalmem = totalmem * info.mem_unit;
+#endif
+
+	/* Return the value, but clamp to SIZE_MAX if necessary. */
+#if UINT64_MAX > SIZE_MAX
+	if (totalmem > SIZE_MAX)
+		*memlimit = SIZE_MAX;
+	else
+		*memlimit = (size_t)totalmem;
+#else
+	*memlimit = totalmem;
+#endif
+
+	/* Success! */
+	return (0);
+}
+#endif /* HAVE_SYSINFO */
+
+#ifndef _WIN32
+static int
+memlimit_rlimit(size_t * memlimit)
+{
+	struct rlimit rl;
+	uint64_t memrlimit;
+
+	/* Find the least of... */
+	memrlimit = (uint64_t)(-1);
+
+	/* ... RLIMIT_AS... */
+#ifdef RLIMIT_AS
+	if (getrlimit(RLIMIT_AS, &rl))
+		return (1);
+	if ((rl.rlim_cur != RLIM_INFINITY) &&
+	    ((uint64_t)rl.rlim_cur < memrlimit))
+		memrlimit = (uint64_t)rl.rlim_cur;
+#endif
+
+	/* ... RLIMIT_DATA... */
+	if (getrlimit(RLIMIT_DATA, &rl))
+		return (1);
+	if ((rl.rlim_cur != RLIM_INFINITY) &&
+	    ((uint64_t)rl.rlim_cur < memrlimit))
+		memrlimit = (uint64_t)rl.rlim_cur;
+
+	/* ... and RLIMIT_RSS. */
+#ifdef RLIMIT_RSS
+	if (getrlimit(RLIMIT_RSS, &rl))
+		return (1);
+	if ((rl.rlim_cur != RLIM_INFINITY) &&
+	    ((uint64_t)rl.rlim_cur < memrlimit))
+		memrlimit = (uint64_t)rl.rlim_cur;
+#endif
+
+	/* Return the value, but clamp to SIZE_MAX if necessary. */
+#if UINT64_MAX > SIZE_MAX
+	if (memrlimit > SIZE_MAX)
+		*memlimit = SIZE_MAX;
+	else
+		*memlimit = (size_t)memrlimit;
+#else
+	*memlimit = memrlimit;
+#endif
+
+	/* Success! */
+	return (0);
+}
+#endif
+
+#ifdef _SC_PHYS_PAGES
+
+/* Some systems define _SC_PAGESIZE instead of _SC_PAGE_SIZE. */
+#ifndef _SC_PAGE_SIZE
+#define _SC_PAGE_SIZE _SC_PAGESIZE
+#endif
+
+static int
+memlimit_sysconf(size_t * memlimit)
+{
+	long pagesize;
+	long physpages;
+	uint64_t totalmem;
+
+	/* Set errno to 0 in order to distinguish "no limit" from "error". */
+	errno = 0;
+
+	/* Read the two limits. */
+	if (((pagesize = sysconf(_SC_PAGE_SIZE)) == -1) ||
+	    ((physpages = sysconf(_SC_PHYS_PAGES)) == -1)) {
+		/*
+		 * Did an error occur?  OS X may return EINVAL due to not
+		 * supporting _SC_PHYS_PAGES in spite of defining it.
+		 */
+		if (errno != 0 && errno != EINVAL)
+			return (1);
+
+		/* If not, there is no limit. */
+		totalmem = (uint64_t)(-1);
+	} else {
+		/* Compute the limit. */
+		totalmem = (uint64_t)(pagesize) * (uint64_t)(physpages);
+	}
+
+	/* Return the value, but clamp to SIZE_MAX if necessary. */
+#if UINT64_MAX > SIZE_MAX
+	if (totalmem > SIZE_MAX)
+		*memlimit = SIZE_MAX;
+	else
+		*memlimit = (size_t)totalmem;
+#else
+	*memlimit = totalmem;
+#endif
+
+	/* Success! */
+	return (0);
+}
+#endif
+
+#ifdef _WIN32
+static int
+memlimit_windows(size_t * memlimit)
+{
+	MEMORYSTATUSEX state;
+	state.dwLength = sizeof(state);
+
+	if(!GlobalMemoryStatusEx (&state))
+		return (1);
+
+
+	*memlimit = state.ullTotalPhys;
+	return (0);
+
+}
+#endif
+
+int
+memtouse(size_t maxmem, double maxmemfrac, size_t * memlimit)
+{
+	size_t usermem_memlimit, memsize_memlimit;
+	size_t sysinfo_memlimit, rlimit_memlimit;
+	size_t sysconf_memlimit, windows_memlimit;
+	size_t memlimit_min;
+	size_t memavail;
+
+	/* Get memory limits. */
+#ifdef HW_USERMEM
+	if (memlimit_sysctl_hw(&usermem_memlimit, HW_USERMEM))
+		return (1);
+#else
+	usermem_memlimit = SIZE_MAX;
+#endif
+#ifdef HW_MEMSIZE
+	if (memlimit_sysctl_hw(&memsize_memlimit, HW_MEMSIZE))
+		return (1);
+#else
+	memsize_memlimit = SIZE_MAX;
+#endif
+#ifdef HAVE_SYSINFO
+	if (memlimit_sysinfo(&sysinfo_memlimit))
+		return (1);
+#else
+	sysinfo_memlimit = SIZE_MAX;
+#endif
+#ifndef _WIN32
+	if (memlimit_rlimit(&rlimit_memlimit))
+		return (1);
+#else
+	rlimit_memlimit = SIZE_MAX;
+#endif
+#ifdef _SC_PHYS_PAGES
+	if (memlimit_sysconf(&sysconf_memlimit))
+		return (1);
+#else
+	sysconf_memlimit = SIZE_MAX;
+#endif
+#ifdef _WIN32
+	if (memlimit_windows(&windows_memlimit))
+		return (1);
+#else
+	windows_memlimit = SIZE_MAX;
+#endif
+
+#ifdef DEBUG
+	fprintf(stderr, "Memory limits are %zu %zu %zu %zu %zu\n",
+	    usermem_memlimit, memsize_memlimit,
+	    sysinfo_memlimit, rlimit_memlimit,
+	    sysconf_memlimit);
+#endif
+
+	/* Find the smallest of them. */
+	memlimit_min = SIZE_MAX;
+	if (memlimit_min > usermem_memlimit)
+		memlimit_min = usermem_memlimit;
+	if (memlimit_min > memsize_memlimit)
+		memlimit_min = memsize_memlimit;
+	if (memlimit_min > sysinfo_memlimit)
+		memlimit_min = sysinfo_memlimit;
+	if (memlimit_min > rlimit_memlimit)
+		memlimit_min = rlimit_memlimit;
+	if (memlimit_min > sysconf_memlimit)
+		memlimit_min = sysconf_memlimit;
+	if (memlimit_min > windows_memlimit)
+		memlimit_min = windows_memlimit;
+
+	/* Only use the specified fraction of the available memory. */
+	if ((maxmemfrac > 0.5) || (maxmemfrac == 0.0))
+		maxmemfrac = 0.5;
+	memavail = (size_t)(maxmemfrac * memlimit_min);
+
+	/* Don't use more than the specified maximum. */
+	if ((maxmem > 0) && (memavail > maxmem))
+		memavail = maxmem;
+
+	/* But always allow at least 1 MiB. */
+	if (memavail < 1048576)
+		memavail = 1048576;
+
+#ifdef DEBUG
+	fprintf(stderr, "Allowing up to %zu memory to be used\n", memavail);
+#endif
+
+	/* Return limit via the provided pointer. */
+	*memlimit = memavail;
+	return (0);
+}
diff -pruN 0.8.0-0.3/scrypt-1.2.1/lib/util/memlimit.h 0.8.20-1/scrypt-1.2.1/lib/util/memlimit.h
--- 0.8.0-0.3/scrypt-1.2.1/lib/util/memlimit.h	1970-01-01 00:00:00.000000000 +0000
+++ 0.8.20-1/scrypt-1.2.1/lib/util/memlimit.h	2022-02-21 10:55:27.000000000 +0000
@@ -0,0 +1,42 @@
+/*-
+ * Copyright 2009 Colin Percival
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file was originally written by Colin Percival as part of the Tarsnap
+ * online backup system.
+ */
+#ifndef _MEMLIMIT_H_
+#define _MEMLIMIT_H_
+
+#include <stddef.h>
+
+/**
+ * memtouse(maxmem, maxmemfrac, memlimit):
+ * Examine the system and return via memlimit the amount of RAM which should
+ * be used -- the specified fraction of the available RAM, but no more than
+ * maxmem, and no less than 1MiB.
+ */
+int memtouse(size_t, double, size_t *);
+
+#endif /* !_MEMLIMIT_H_ */
diff -pruN 0.8.0-0.3/scrypt-1.2.1/libcperciva/alg/sha256.c 0.8.20-1/scrypt-1.2.1/libcperciva/alg/sha256.c
--- 0.8.0-0.3/scrypt-1.2.1/libcperciva/alg/sha256.c	1970-01-01 00:00:00.000000000 +0000
+++ 0.8.20-1/scrypt-1.2.1/libcperciva/alg/sha256.c	2022-02-21 10:55:27.000000000 +0000
@@ -0,0 +1,572 @@
+#include <assert.h>
+#include <stdint.h>
+#include <string.h>
+
+#include "insecure_memzero.h"
+#include "sysendian.h"
+
+#include "sha256.h"
+
+#define _USE_RESTRICT 0
+
+/*
+ * Encode a length len/4 vector of (uint32_t) into a length len vector of
+ * (uint8_t) in big-endian form.  Assumes len is a multiple of 4.
+ */
+static void
+be32enc_vect(uint8_t * dst, const uint32_t * src, size_t len)
+{
+	size_t i;
+
+	/* Sanity-check. */
+	assert(len % 4 == 0);
+
+	/* Encode vector, one word at a time. */
+	for (i = 0; i < len / 4; i++)
+		be32enc(dst + i * 4, src[i]);
+}
+
+/*
+ * Decode a big-endian length len vector of (uint8_t) into a length
+ * len/4 vector of (uint32_t).  Assumes len is a multiple of 4.
+ */
+static void
+be32dec_vect(uint32_t * dst, const uint8_t * src, size_t len)
+{
+	size_t i;
+
+	/* Sanity-check. */
+	assert(len % 4 == 0);
+
+	/* Decode vector, one word at a time. */
+	for (i = 0; i < len / 4; i++)
+		dst[i] = be32dec(src + i * 4);
+}
+
+/* SHA256 round constants. */
+static const uint32_t Krnd[64] = {
+	0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
+	0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
+	0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
+	0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
+	0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
+	0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
+	0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
+	0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
+	0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
+	0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
+	0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
+	0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
+	0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
+	0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
+	0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
+	0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
+};
+
+/* Elementary functions used by SHA256 */
+#define Ch(x, y, z)	((x & (y ^ z)) ^ z)
+#define Maj(x, y, z)	((x & (y | z)) | (y & z))
+#define SHR(x, n)	(x >> n)
+#define ROTR(x, n)	((x >> n) | (x << (32 - n)))
+#define S0(x)		(ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22))
+#define S1(x)		(ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25))
+#define s0(x)		(ROTR(x, 7) ^ ROTR(x, 18) ^ SHR(x, 3))
+#define s1(x)		(ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10))
+
+/* SHA256 round function */
+#define RND(a, b, c, d, e, f, g, h, k)			\
+	h += S1(e) + Ch(e, f, g) + k;			\
+	d += h;						\
+	h += S0(a) + Maj(a, b, c);
+
+/* Adjusted round function for rotating state */
+#define RNDr(S, W, i, ii)			\
+	RND(S[(64 - i) % 8], S[(65 - i) % 8],	\
+	    S[(66 - i) % 8], S[(67 - i) % 8],	\
+	    S[(68 - i) % 8], S[(69 - i) % 8],	\
+	    S[(70 - i) % 8], S[(71 - i) % 8],	\
+	    W[i + ii] + Krnd[i + ii])
+
+/* Message schedule computation */
+#define MSCH(W, ii, i)				\
+	W[i + ii + 16] = s1(W[i + ii + 14]) + W[i + ii + 9] + s0(W[i + ii + 1]) + W[i + ii]
+
+/*
+ * SHA256 block compression function.  The 256-bit state is transformed via
+ * the 512-bit input block to produce a new state.
+ */
+#if _USE_RESTRICT
+static void
+SHA256_Transform(uint32_t state[static restrict 8],
+    const uint8_t block[static restrict 64],
+    uint32_t W[static restrict 64], uint32_t S[static restrict 8])
+#else
+static void
+SHA256_Transform(uint32_t state[8],
+    const uint8_t block[64],
+    uint32_t W[64], uint32_t S[8])
+#endif
+{
+	int i;
+
+	/* 1. Prepare the first part of the message schedule W. */
+	be32dec_vect(W, block, 64);
+
+	/* 2. Initialize working variables. */
+	memcpy(S, state, 32);
+
+	/* 3. Mix. */
+	for (i = 0; i < 64; i += 16) {
+		RNDr(S, W, 0, i);
+		RNDr(S, W, 1, i);
+		RNDr(S, W, 2, i);
+		RNDr(S, W, 3, i);
+		RNDr(S, W, 4, i);
+		RNDr(S, W, 5, i);
+		RNDr(S, W, 6, i);
+		RNDr(S, W, 7, i);
+		RNDr(S, W, 8, i);
+		RNDr(S, W, 9, i);
+		RNDr(S, W, 10, i);
+		RNDr(S, W, 11, i);
+		RNDr(S, W, 12, i);
+		RNDr(S, W, 13, i);
+		RNDr(S, W, 14, i);
+		RNDr(S, W, 15, i);
+
+		if (i == 48)
+			break;
+		MSCH(W, 0, i);
+		MSCH(W, 1, i);
+		MSCH(W, 2, i);
+		MSCH(W, 3, i);
+		MSCH(W, 4, i);
+		MSCH(W, 5, i);
+		MSCH(W, 6, i);
+		MSCH(W, 7, i);
+		MSCH(W, 8, i);
+		MSCH(W, 9, i);
+		MSCH(W, 10, i);
+		MSCH(W, 11, i);
+		MSCH(W, 12, i);
+		MSCH(W, 13, i);
+		MSCH(W, 14, i);
+		MSCH(W, 15, i);
+	}
+
+	/* 4. Mix local working variables into global state. */
+	for (i = 0; i < 8; i++)
+		state[i] += S[i];
+}
+
+static const uint8_t PAD[64] = {
+	0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/* Add padding and terminating bit-count. */
+#if _USE_RESTRICT
+static void
+SHA256_Pad(SHA256_CTX * ctx, uint32_t tmp32[static restrict 72])
+#else
+static void
+SHA256_Pad(SHA256_CTX * ctx, uint32_t tmp32[72])
+#endif
+{
+	size_t r;
+
+	/* Figure out how many bytes we have buffered. */
+	r = (ctx->count >> 3) & 0x3f;
+
+	/* Pad to 56 mod 64, transforming if we finish a block en route. */
+	if (r < 56) {
+		/* Pad to 56 mod 64. */
+		memcpy(&ctx->buf[r], PAD, 56 - r);
+	} else {
+		/* Finish the current block and mix. */
+		memcpy(&ctx->buf[r], PAD, 64 - r);
+		SHA256_Transform(ctx->state, ctx->buf, &tmp32[0], &tmp32[64]);
+
+		/* The start of the final block is all zeroes. */
+		memset(&ctx->buf[0], 0, 56);
+	}
+
+	/* Add the terminating bit-count. */
+	be64enc(&ctx->buf[56], ctx->count);
+
+	/* Mix in the final block. */
+	SHA256_Transform(ctx->state, ctx->buf, &tmp32[0], &tmp32[64]);
+}
+
+/* Magic initialization constants. */
+static const uint32_t initial_state[8] = {
+	0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A,
+	0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19
+};
+
+/**
+ * SHA256_Init(ctx):
+ * Initialize the SHA256 context ${ctx}.
+ */
+void
+SHA256_Init(SHA256_CTX * ctx)
+{
+
+	/* Zero bits processed so far. */
+	ctx->count = 0;
+
+	/* Initialize state. */
+	memcpy(ctx->state, initial_state, sizeof(initial_state));
+}
+
+/**
+ * SHA256_Update(ctx, in, len):
+ * Input ${len} bytes from ${in} into the SHA256 context ${ctx}.
+ */
+#if _USE_RESTRICT
+static void
+_SHA256_Update(SHA256_CTX * ctx, const void * in, size_t len,
+    uint32_t tmp32[static restrict 72])
+#else
+static void
+_SHA256_Update(SHA256_CTX * ctx, const void * in, size_t len,
+    uint32_t tmp32[72])
+#endif
+{
+	uint32_t r;
+	const uint8_t * src = in;
+
+	/* Return immediately if we have nothing to do. */
+	if (len == 0)
+		return;
+
+	/* Number of bytes left in the buffer from previous updates. */
+	r = (ctx->count >> 3) & 0x3f;
+
+	/* Update number of bits. */
+	ctx->count += (uint64_t)(len) << 3;
+
+	/* Handle the case where we don't need to perform any transforms. */
+	if (len < 64 - r) {
+		memcpy(&ctx->buf[r], src, len);
+		return;
+	}
+
+	/* Finish the current block. */
+	memcpy(&ctx->buf[r], src, 64 - r);
+	SHA256_Transform(ctx->state, ctx->buf, &tmp32[0], &tmp32[64]);
+	src += 64 - r;
+	len -= 64 - r;
+
+	/* Perform complete blocks. */
+	while (len >= 64) {
+		SHA256_Transform(ctx->state, src, &tmp32[0], &tmp32[64]);
+		src += 64;
+		len -= 64;
+	}
+
+	/* Copy left over data into buffer. */
+	memcpy(ctx->buf, src, len);
+}
+
+/* Wrapper function for intermediate-values sanitization. */
+void
+SHA256_Update(SHA256_CTX * ctx, const void * in, size_t len)
+{
+	uint32_t tmp32[72];
+
+	/* Call the real function. */
+	_SHA256_Update(ctx, in, len, tmp32);
+
+	/* Clean the stack. */
+	insecure_memzero(tmp32, 288);
+}
+
+/**
+ * SHA256_Final(digest, ctx):
+ * Output the SHA256 hash of the data input to the context ${ctx} into the
+ * buffer ${digest}.
+ */
+#if _USE_RESTRICT
+static void
+_SHA256_Final(uint8_t digest[32], SHA256_CTX * ctx,
+    uint32_t tmp32[static restrict 72])
+#else
+static void
+_SHA256_Final(uint8_t digest[32], SHA256_CTX * ctx,
+    uint32_t tmp32[72])
+#endif
+{
+
+	/* Add padding. */
+	SHA256_Pad(ctx, tmp32);
+
+	/* Write the hash. */
+	be32enc_vect(digest, ctx->state, 32);
+}
+
+/* Wrapper function for intermediate-values sanitization. */
+void
+SHA256_Final(uint8_t digest[32], SHA256_CTX * ctx)
+{
+	uint32_t tmp32[72];
+
+	/* Call the real function. */
+	_SHA256_Final(digest, ctx, tmp32);
+
+	/* Clear the context state. */
+	insecure_memzero(ctx, sizeof(SHA256_CTX));
+
+	/* Clean the stack. */
+	insecure_memzero(tmp32, 288);
+}
+
+/**
+ * SHA256_Buf(in, len, digest):
+ * Compute the SHA256 hash of ${len} bytes from ${in} and write it to ${digest}.
+ */
+void
+SHA256_Buf(const void * in, size_t len, uint8_t digest[32])
+{
+	SHA256_CTX ctx;
+	uint32_t tmp32[72];
+
+	SHA256_Init(&ctx);
+	_SHA256_Update(&ctx, in, len, tmp32);
+	_SHA256_Final(digest, &ctx, tmp32);
+
+	/* Clean the stack. */
+	insecure_memzero(&ctx, sizeof(SHA256_CTX));
+	insecure_memzero(tmp32, 288);
+}
+
+/**
+ * HMAC_SHA256_Init(ctx, K, Klen):
+ * Initialize the HMAC-SHA256 context ${ctx} with ${Klen} bytes of key from
+ * ${K}.
+ */
+#if _USE_RESTRICT
+static void
+_HMAC_SHA256_Init(HMAC_SHA256_CTX * ctx, const void * _K, size_t Klen,
+    uint32_t tmp32[static restrict 72], uint8_t pad[static restrict 64],
+    uint8_t khash[static restrict 32])
+#else
+static void
+_HMAC_SHA256_Init(HMAC_SHA256_CTX * ctx, const void * _K, size_t Klen,
+    uint32_t tmp32[72], uint8_t pad[64],
+    uint8_t khash[32])
+#endif
+{
+	const uint8_t * K = _K;
+	size_t i;
+
+	/* If Klen > 64, the key is really SHA256(K). */
+	if (Klen > 64) {
+		SHA256_Init(&ctx->ictx);
+		_SHA256_Update(&ctx->ictx, K, Klen, tmp32);
+		_SHA256_Final(khash, &ctx->ictx, tmp32);
+		K = khash;
+		Klen = 32;
+	}
+
+	/* Inner SHA256 operation is SHA256(K xor [block of 0x36] || data). */
+	SHA256_Init(&ctx->ictx);
+	memset(pad, 0x36, 64);
+	for (i = 0; i < Klen; i++)
+		pad[i] ^= K[i];
+	_SHA256_Update(&ctx->ictx, pad, 64, tmp32);
+
+	/* Outer SHA256 operation is SHA256(K xor [block of 0x5c] || hash). */
+	SHA256_Init(&ctx->octx);
+	memset(pad, 0x5c, 64);
+	for (i = 0; i < Klen; i++)
+		pad[i] ^= K[i];
+	_SHA256_Update(&ctx->octx, pad, 64, tmp32);
+}
+
+/* Wrapper function for intermediate-values sanitization. */
+void
+HMAC_SHA256_Init(HMAC_SHA256_CTX * ctx, const void * _K, size_t Klen)
+{
+	uint32_t tmp32[72];
+	uint8_t pad[64];
+	uint8_t khash[32];
+
+	/* Call the real function. */
+	_HMAC_SHA256_Init(ctx, _K, Klen, tmp32, pad, khash);
+
+	/* Clean the stack. */
+	insecure_memzero(tmp32, 288);
+	insecure_memzero(khash, 32);
+	insecure_memzero(pad, 64);
+}
+
+/**
+ * HMAC_SHA256_Update(ctx, in, len):
+ * Input ${len} bytes from ${in} into the HMAC-SHA256 context ${ctx}.
+ */
+#if _USE_RESTRICT
+static void
+_HMAC_SHA256_Update(HMAC_SHA256_CTX * ctx, const void * in, size_t len,
+    uint32_t tmp32[static restrict 72])
+#else
+static void
+_HMAC_SHA256_Update(HMAC_SHA256_CTX * ctx, const void * in, size_t len,
+    uint32_t tmp32[72])
+#endif
+{
+
+	/* Feed data to the inner SHA256 operation. */
+	_SHA256_Update(&ctx->ictx, in, len, tmp32);
+}
+
+/* Wrapper function for intermediate-values sanitization. */
+void
+HMAC_SHA256_Update(HMAC_SHA256_CTX * ctx, const void * in, size_t len)
+{
+	uint32_t tmp32[72];
+
+	/* Call the real function. */
+	_HMAC_SHA256_Update(ctx, in, len, tmp32);
+
+	/* Clean the stack. */
+	insecure_memzero(tmp32, 288);
+}
+
+/**
+ * HMAC_SHA256_Final(digest, ctx):
+ * Output the HMAC-SHA256 of the data input to the context ${ctx} into the
+ * buffer ${digest}.
+ */
+#if _USE_RESTRICT
+static void
+_HMAC_SHA256_Final(uint8_t digest[32], HMAC_SHA256_CTX * ctx,
+    uint32_t tmp32[static restrict 72], uint8_t ihash[static restrict 32])
+#else
+static void
+_HMAC_SHA256_Final(uint8_t digest[32], HMAC_SHA256_CTX * ctx,
+    uint32_t tmp32[72], uint8_t ihash[32])
+#endif
+{
+
+	/* Finish the inner SHA256 operation. */
+	_SHA256_Final(ihash, &ctx->ictx, tmp32);
+
+	/* Feed the inner hash to the outer SHA256 operation. */
+	_SHA256_Update(&ctx->octx, ihash, 32, tmp32);
+
+	/* Finish the outer SHA256 operation. */
+	_SHA256_Final(digest, &ctx->octx, tmp32);
+}
+
+/* Wrapper function for intermediate-values sanitization. */
+void
+HMAC_SHA256_Final(uint8_t digest[32], HMAC_SHA256_CTX * ctx)
+{
+	uint32_t tmp32[72];
+	uint8_t ihash[32];
+
+	/* Call the real function. */
+	_HMAC_SHA256_Final(digest, ctx, tmp32, ihash);
+
+	/* Clean the stack. */
+	insecure_memzero(tmp32, 288);
+	insecure_memzero(ihash, 32);
+}
+
+/**
+ * HMAC_SHA256_Buf(K, Klen, in, len, digest):
+ * Compute the HMAC-SHA256 of ${len} bytes from ${in} using the key ${K} of
+ * length ${Klen}, and write the result to ${digest}.
+ */
+void
+HMAC_SHA256_Buf(const void * K, size_t Klen, const void * in, size_t len,
+    uint8_t digest[32])
+{
+	HMAC_SHA256_CTX ctx;
+	uint32_t tmp32[72];
+	uint8_t tmp8[96];
+
+	_HMAC_SHA256_Init(&ctx, K, Klen, tmp32, &tmp8[0], &tmp8[64]);
+	_HMAC_SHA256_Update(&ctx, in, len, tmp32);
+	_HMAC_SHA256_Final(digest, &ctx, tmp32, &tmp8[0]);
+
+	/* Clean the stack. */
+	insecure_memzero(&ctx, sizeof(HMAC_SHA256_CTX));
+	insecure_memzero(tmp32, 288);
+	insecure_memzero(tmp8, 96);
+}
+
+/**
+ * PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, c, buf, dkLen):
+ * Compute PBKDF2(passwd, salt, c, dkLen) using HMAC-SHA256 as the PRF, and
+ * write the output to buf.  The value dkLen must be at most 32 * (2^32 - 1).
+ */
+void
+PBKDF2_SHA256(const uint8_t * passwd, size_t passwdlen, const uint8_t * salt,
+    size_t saltlen, uint64_t c, uint8_t * buf, size_t dkLen)
+{
+	HMAC_SHA256_CTX Phctx, PShctx, hctx;
+	uint32_t tmp32[72];
+	uint8_t tmp8[96];
+	size_t i;
+	uint8_t ivec[4];
+	uint8_t U[32];
+	uint8_t T[32];
+	uint64_t j;
+	int k;
+	size_t clen;
+
+	/* Sanity-check. */
+	assert(dkLen <= 32 * (size_t)(UINT32_MAX));
+
+	/* Compute HMAC state after processing P. */
+	_HMAC_SHA256_Init(&Phctx, passwd, passwdlen,
+	    tmp32, &tmp8[0], &tmp8[64]);
+
+	/* Compute HMAC state after processing P and S. */
+	memcpy(&PShctx, &Phctx, sizeof(HMAC_SHA256_CTX));
+	_HMAC_SHA256_Update(&PShctx, salt, saltlen, tmp32);
+
+	/* Iterate through the blocks. */
+	for (i = 0; i * 32 < dkLen; i++) {
+		/* Generate INT(i + 1). */
+		be32enc(ivec, (uint32_t)(i + 1));
+
+		/* Compute U_1 = PRF(P, S || INT(i)). */
+		memcpy(&hctx, &PShctx, sizeof(HMAC_SHA256_CTX));
+		_HMAC_SHA256_Update(&hctx, ivec, 4, tmp32);
+		_HMAC_SHA256_Final(U, &hctx, tmp32, tmp8);
+
+		/* T_i = U_1 ... */
+		memcpy(T, U, 32);
+
+		for (j = 2; j <= c; j++) {
+			/* Compute U_j. */
+			memcpy(&hctx, &Phctx, sizeof(HMAC_SHA256_CTX));
+			_HMAC_SHA256_Update(&hctx, U, 32, tmp32);
+			_HMAC_SHA256_Final(U, &hctx, tmp32, tmp8);
+
+			/* ... xor U_j ... */
+			for (k = 0; k < 32; k++)
+				T[k] ^= U[k];
+		}
+
+		/* Copy as many bytes as necessary into buf. */
+		clen = dkLen - i * 32;
+		if (clen > 32)
+			clen = 32;
+		memcpy(&buf[i * 32], T, clen);
+	}
+
+	/* Clean the stack. */
+	insecure_memzero(&Phctx, sizeof(HMAC_SHA256_CTX));
+	insecure_memzero(&PShctx, sizeof(HMAC_SHA256_CTX));
+	insecure_memzero(&hctx, sizeof(HMAC_SHA256_CTX));
+	insecure_memzero(tmp32, 288);
+	insecure_memzero(tmp8, 96);
+	insecure_memzero(U, 32);
+	insecure_memzero(T, 32);
+}
diff -pruN 0.8.0-0.3/scrypt-1.2.1/libcperciva/alg/sha256.h 0.8.20-1/scrypt-1.2.1/libcperciva/alg/sha256.h
--- 0.8.0-0.3/scrypt-1.2.1/libcperciva/alg/sha256.h	1970-01-01 00:00:00.000000000 +0000
+++ 0.8.20-1/scrypt-1.2.1/libcperciva/alg/sha256.h	2022-02-21 10:55:27.000000000 +0000
@@ -0,0 +1,95 @@
+#ifndef _SHA256_H_
+#define _SHA256_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+/*
+ * Use #defines in order to avoid namespace collisions with anyone else's
+ * SHA256 code (e.g., the code in OpenSSL).
+ */
+#define SHA256_Init libcperciva_SHA256_Init
+#define SHA256_Update libcperciva_SHA256_Update
+#define SHA256_Final libcperciva_SHA256_Final
+#define SHA256_Buf libcperciva_SHA256_Buf
+#define SHA256_CTX libcperciva_SHA256_CTX
+#define HMAC_SHA256_Init libcperciva_HMAC_SHA256_Init
+#define HMAC_SHA256_Update libcperciva_HMAC_SHA256_Update
+#define HMAC_SHA256_Final libcperciva_HMAC_SHA256_Final
+#define HMAC_SHA256_Buf libcperciva_HMAC_SHA256_Buf
+#define HMAC_SHA256_CTX libcperciva_HMAC_SHA256_CTX
+
+/* Context structure for SHA256 operations. */
+typedef struct {
+	uint32_t state[8];
+	uint64_t count;
+	uint8_t buf[64];
+} SHA256_CTX;
+
+/**
+ * SHA256_Init(ctx):
+ * Initialize the SHA256 context ${ctx}.
+ */
+void SHA256_Init(SHA256_CTX *);
+
+/**
+ * SHA256_Update(ctx, in, len):
+ * Input ${len} bytes from ${in} into the SHA256 context ${ctx}.
+ */
+void SHA256_Update(SHA256_CTX *, const void *, size_t);
+
+/**
+ * SHA256_Final(digest, ctx):
+ * Output the SHA256 hash of the data input to the context ${ctx} into the
+ * buffer ${digest}.
+ */
+void SHA256_Final(uint8_t[32], SHA256_CTX *);
+
+/**
+ * SHA256_Buf(in, len, digest):
+ * Compute the SHA256 hash of ${len} bytes from ${in} and write it to ${digest}.
+ */
+void SHA256_Buf(const void *, size_t, uint8_t[32]);
+
+/* Context structure for HMAC-SHA256 operations. */
+typedef struct {
+	SHA256_CTX ictx;
+	SHA256_CTX octx;
+} HMAC_SHA256_CTX;
+
+/**
+ * HMAC_SHA256_Init(ctx, K, Klen):
+ * Initialize the HMAC-SHA256 context ${ctx} with ${Klen} bytes of key from
+ * ${K}.
+ */
+void HMAC_SHA256_Init(HMAC_SHA256_CTX *, const void *, size_t);
+
+/**
+ * HMAC_SHA256_Update(ctx, in, len):
+ * Input ${len} bytes from ${in} into the HMAC-SHA256 context ${ctx}.
+ */
+void HMAC_SHA256_Update(HMAC_SHA256_CTX *, const void *, size_t);
+
+/**
+ * HMAC_SHA256_Final(digest, ctx):
+ * Output the HMAC-SHA256 of the data input to the context ${ctx} into the
+ * buffer ${digest}.
+ */
+void HMAC_SHA256_Final(uint8_t[32], HMAC_SHA256_CTX *);
+
+/**
+ * HMAC_SHA256_Buf(K, Klen, in, len, digest):
+ * Compute the HMAC-SHA256 of ${len} bytes from ${in} using the key ${K} of
+ * length ${Klen}, and write the result to ${digest}.
+ */
+void HMAC_SHA256_Buf(const void *, size_t, const void *, size_t, uint8_t[32]);
+
+/**
+ * PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, c, buf, dkLen):
+ * Compute PBKDF2(passwd, salt, c, dkLen) using HMAC-SHA256 as the PRF, and
+ * write the output to buf.  The value dkLen must be at most 32 * (2^32 - 1).
+ */
+void PBKDF2_SHA256(const uint8_t *, size_t, const uint8_t *, size_t,
+    uint64_t, uint8_t *, size_t);
+
+#endif /* !_SHA256_H_ */
diff -pruN 0.8.0-0.3/scrypt-1.2.1/libcperciva/cpusupport/cpusupport.h 0.8.20-1/scrypt-1.2.1/libcperciva/cpusupport/cpusupport.h
--- 0.8.0-0.3/scrypt-1.2.1/libcperciva/cpusupport/cpusupport.h	1970-01-01 00:00:00.000000000 +0000
+++ 0.8.20-1/scrypt-1.2.1/libcperciva/cpusupport/cpusupport.h	2022-02-21 10:55:27.000000000 +0000
@@ -0,0 +1,106 @@
+#ifndef _CPUSUPPORT_H_
+#define _CPUSUPPORT_H_
+
+/*
+ * To enable support for non-portable CPU features at compile time, one or
+ * more CPUSUPPORT_ARCH_FEATURE macros should be defined.  This can be done
+ * directly on the compiler command line via -D CPUSUPPORT_ARCH_FEATURE or
+ * -D CPUSUPPORT_ARCH_FEATURE=1; or a file can be created with the
+ * necessary #define lines and then -D CPUSUPPORT_CONFIG_FILE=cpuconfig.h
+ * (or similar) can be provided to include that file here.
+ */
+#ifdef CPUSUPPORT_CONFIG_FILE
+#include CPUSUPPORT_CONFIG_FILE
+#endif
+
+/**
+ * The CPUSUPPORT_FEATURE macro declares the necessary variables and
+ * functions for detecting CPU feature support at run time.  The function
+ * defined in the macro acts to cache the result of the ..._detect function
+ * using the ..._present and ..._init variables.  The _detect function and the
+ * _present and _init variables are turn defined by CPUSUPPORT_FEATURE_DECL in
+ * appropriate cpusupport_foo_bar.c file.
+ *
+ * In order to allow CPUSUPPORT_FEATURE to be used for features which do not
+ * have corresponding CPUSUPPORT_FEATURE_DECL blocks in another source file,
+ * we abuse the C preprocessor: If CPUSUPPORT_${enabler} is defined to 1, then
+ * we access _present_1, _init_1, and _detect_1; but if it is not defined, we
+ * access _present_CPUSUPPORT_${enabler} etc., which we define as static, thus
+ * preventing the compiler from emitting a reference to an external symbol.
+ *
+ * In this way, it becomes possible to issue CPUSUPPORT_FEATURE invocations
+ * for nonexistent features without running afoul of the requirement that
+ * "If an identifier declared with external linkage is used... in the entire
+ * program there shall be exactly one external definition" (C99 standard, 6.9
+ * paragraph 5).  In practice, this means that users of the cpusupport code
+ * can omit build and runtime detection files without changing the framework
+ * code.
+ */
+#define CPUSUPPORT_FEATURE__(arch_feature, enabler, enabled)					\
+	static int cpusupport_ ## arch_feature ## _present ## _CPUSUPPORT_ ## enabler;		\
+	static int cpusupport_ ## arch_feature ## _init ## _CPUSUPPORT_ ## enabler;		\
+	static inline int cpusupport_ ## arch_feature ## _detect ## _CPUSUPPORT_ ## enabler(void) { return (0); }	\
+	extern int cpusupport_ ## arch_feature ## _present_ ## enabled;				\
+	extern int cpusupport_ ## arch_feature ## _init_ ## enabled;				\
+	int cpusupport_ ## arch_feature ## _detect_ ## enabled(void);				\
+												\
+	static inline int									\
+	cpusupport_ ## arch_feature(void)							\
+	{											\
+												\
+		if (cpusupport_ ## arch_feature ## _present_ ## enabled)			\
+			return (1);								\
+		else if (cpusupport_ ## arch_feature ## _init_ ## enabled)			\
+			return (0);								\
+		cpusupport_ ## arch_feature ## _present_ ## enabled = 				\
+		    cpusupport_ ## arch_feature ## _detect_ ## enabled();			\
+		cpusupport_ ## arch_feature ## _init_ ## enabled = 1;				\
+		return (cpusupport_ ## arch_feature ## _present_ ## enabled); 			\
+	}											\
+	static void (* cpusupport_ ## arch_feature ## _dummyptr)(void);				\
+	static inline void									\
+	cpusupport_ ## arch_feature ## _dummyfunc(void)						\
+	{											\
+												\
+		(void)cpusupport_ ## arch_feature ## _present ## _CPUSUPPORT_ ## enabler;	\
+		(void)cpusupport_ ## arch_feature ## _init ## _CPUSUPPORT_ ## enabler;		\
+		(void)cpusupport_ ## arch_feature ## _detect ## _CPUSUPPORT_ ## enabler;	\
+		(void)cpusupport_ ## arch_feature ## _present_ ## enabled;			\
+		(void)cpusupport_ ## arch_feature ## _init_ ## enabled;				\
+		(void)cpusupport_ ## arch_feature ## _detect_ ## enabled;			\
+		(void)cpusupport_ ## arch_feature ## _dummyptr;					\
+	}											\
+	static void (* cpusupport_ ## arch_feature ## _dummyptr)(void) = cpusupport_ ## arch_feature ## _dummyfunc;	\
+	struct cpusupport_ ## arch_feature ## _dummy
+#define CPUSUPPORT_FEATURE_(arch_feature, enabler, enabled)	\
+	CPUSUPPORT_FEATURE__(arch_feature, enabler, enabled)
+#define CPUSUPPORT_FEATURE(arch, feature, enabler)				\
+	CPUSUPPORT_FEATURE_(arch ## _ ## feature, enabler, CPUSUPPORT_ ## enabler)
+
+/*
+ * CPUSUPPORT_FEATURE_DECL(arch, feature):
+ * Macro which defines variables and provides a function declaration for
+ * detecting the presence of "feature" on the "arch" architecture.  The
+ * function body following this macro expansion must return nonzero if the
+ * feature is present, or zero if the feature is not present or the detection
+ * fails for any reason.
+ */
+#define CPUSUPPORT_FEATURE_DECL(arch, feature)				\
+	int cpusupport_ ## arch ## _ ## feature ## _present_1 = 0;	\
+	int cpusupport_ ## arch ## _ ## feature ## _init_1 = 0;		\
+	int cpusupport_ ## arch ## _ ## feature ## _detect_1(void); \
+	int								\
+	cpusupport_ ## arch ## _ ## feature ## _detect_1(void)
+
+/*
+ * List of features.  If a feature here is not enabled by the appropriate
+ * CPUSUPPORT_ARCH_FEATURE macro being defined, it has no effect; but if the
+ * relevant macro may be defined (e.g., by Build/cpusupport.sh successfully
+ * compiling Build/cpusupport-ARCH-FEATURE.c) then the C file containing the
+ * corresponding run-time detection code (cpusupport_arch_feature.c) must be
+ * compiled and linked in.
+ */
+CPUSUPPORT_FEATURE(x86, aesni, X86_AESNI);
+CPUSUPPORT_FEATURE(x86, sse2, X86_SSE2);
+
+#endif /* !_CPUSUPPORT_H_ */
diff -pruN 0.8.0-0.3/scrypt-1.2.1/libcperciva/crypto/crypto_aes_aesni.c 0.8.20-1/scrypt-1.2.1/libcperciva/crypto/crypto_aes_aesni.c
--- 0.8.0-0.3/scrypt-1.2.1/libcperciva/crypto/crypto_aes_aesni.c	1970-01-01 00:00:00.000000000 +0000
+++ 0.8.20-1/scrypt-1.2.1/libcperciva/crypto/crypto_aes_aesni.c	2022-02-21 10:55:27.000000000 +0000
@@ -0,0 +1,239 @@
+#include "cpusupport.h"
+#ifdef CPUSUPPORT_X86_AESNI
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <wmmintrin.h>
+
+#include "insecure_memzero.h"
+#include "warnp.h"
+
+#include "crypto_aes_aesni.h"
+
+/* Expanded-key structure. */
+struct crypto_aes_key_aesni {
+	uint8_t rkeys_buf[15 * sizeof(__m128i) + (sizeof(__m128i) - 1)];
+	__m128i * rkeys;
+	size_t nr;
+};
+
+/* Compute an AES-128 round key. */
+#define MKRKEY128(rkeys, i, rcon) do {				\
+	__m128i _s = rkeys[i - 1];				\
+	__m128i _t = rkeys[i - 1];				\
+	_s = _mm_xor_si128(_s, _mm_slli_si128(_s, 4));		\
+	_s = _mm_xor_si128(_s, _mm_slli_si128(_s, 8));		\
+	_t = _mm_aeskeygenassist_si128(_t, rcon);		\
+	_t = _mm_shuffle_epi32(_t, 0xff);			\
+	rkeys[i] = _mm_xor_si128(_s, _t);			\
+} while (0)
+
+/**
+ * crypto_aes_key_expand_128_aesni(key, rkeys):
+ * Expand the 128-bit AES key ${key} into the 11 round keys ${rkeys}.  This
+ * implementation uses x86 AESNI instructions, and should only be used if
+ * CPUSUPPORT_X86_AESNI is defined and cpusupport_x86_aesni() returns nonzero.
+ */
+static void
+crypto_aes_key_expand_128_aesni(const uint8_t key[16], __m128i rkeys[11])
+{
+
+	/* The first round key is just the key. */
+	/**
+	 * XXX Compiler breakage:
+	 * The intrinsic defined by Intel for _mm_loadu_si128 defines it as
+	 * taking a (const __m128i *) parameter.  This forces us to write a
+	 * bug: The cast to (const __m128i *) is invalid since it increases
+	 * the alignment requirement of the pointer.  Alas, until compilers
+	 * get fixed intrinsics, all we can do is code the bug and require
+	 * that alignment-requirement-increasing compiler warnings get
+	 * disabled.
+	 */
+	rkeys[0] = _mm_loadu_si128((const __m128i *)&key[0]);
+
+	/*
+	 * Each of the remaining round keys are computed from the preceding
+	 * round key: rotword+subword+rcon (provided as aeskeygenassist) to
+	 * compute the 'temp' value, then xor with 1, 2, 3, or all 4 of the
+	 * 32-bit words from the preceding round key.  Unfortunately, 'rcon'
+	 * is encoded as an immediate value, so we need to write the loop out
+	 * ourselves rather than allowing the compiler to expand it.
+	 */
+	MKRKEY128(rkeys, 1, 0x01);
+	MKRKEY128(rkeys, 2, 0x02);
+	MKRKEY128(rkeys, 3, 0x04);
+	MKRKEY128(rkeys, 4, 0x08);
+	MKRKEY128(rkeys, 5, 0x10);
+	MKRKEY128(rkeys, 6, 0x20);
+	MKRKEY128(rkeys, 7, 0x40);
+	MKRKEY128(rkeys, 8, 0x80);
+	MKRKEY128(rkeys, 9, 0x1b);
+	MKRKEY128(rkeys, 10, 0x36);
+}
+
+/* Compute an AES-256 round key. */
+#define MKRKEY256(rkeys, i, shuffle, rcon)	do {		\
+	__m128i _s = rkeys[i - 2];				\
+	__m128i _t = rkeys[i - 1];				\
+	_s = _mm_xor_si128(_s, _mm_slli_si128(_s, 4));		\
+	_s = _mm_xor_si128(_s, _mm_slli_si128(_s, 8));		\
+	_t = _mm_aeskeygenassist_si128(_t, rcon);		\
+	_t = _mm_shuffle_epi32(_t, shuffle);			\
+	rkeys[i] = _mm_xor_si128(_s, _t);			\
+} while (0)
+
+/**
+ * crypto_aes_key_expand_256_aesni(key, rkeys):
+ * Expand the 256-bit AES key ${key} into the 15 round keys ${rkeys}.  This
+ * implementation uses x86 AESNI instructions, and should only be used if
+ * CPUSUPPORT_X86_AESNI is defined and cpusupport_x86_aesni() returns nonzero.
+ */
+static void
+crypto_aes_key_expand_256_aesni(const uint8_t key[32], __m128i rkeys[15])
+{
+
+	/* The first two round keys are just the key. */
+	/**
+	 * XXX Compiler breakage:
+	 * The intrinsic defined by Intel for _mm_loadu_si128 defines it as
+	 * taking a (const __m128i *) parameter.  This forces us to write a
+	 * bug: The cast to (const __m128i *) is invalid since it increases
+	 * the alignment requirement of the pointer.  Alas, until compilers
+	 * get fixed intrinsics, all we can do is code the bug and require
+	 * that alignment-requirement-increasing compiler warnings get
+	 * disabled.
+	 */
+	rkeys[0] = _mm_loadu_si128((const __m128i *)&key[0]);
+	rkeys[1] = _mm_loadu_si128((const __m128i *)&key[16]);
+
+	/*
+	 * Each of the remaining round keys are computed from the preceding
+	 * pair of keys.  Even rounds use rotword+subword+rcon, while odd
+	 * rounds just use subword; the aeskeygenassist instruction computes
+	 * both, and we use 0xff or 0xaa to select the one we need.  The rcon
+	 * value used is irrelevant for odd rounds since we ignore the value
+	 * which it feeds into.  Unfortunately, the 'shuffle' and 'rcon'
+	 * values are encoded into the instructions as immediates, so we need
+	 * to write the loop out ourselves rather than allowing the compiler
+	 * to expand it.
+	 */
+	MKRKEY256(rkeys, 2, 0xff, 0x01);
+	MKRKEY256(rkeys, 3, 0xaa, 0x00);
+	MKRKEY256(rkeys, 4, 0xff, 0x02);
+	MKRKEY256(rkeys, 5, 0xaa, 0x00);
+	MKRKEY256(rkeys, 6, 0xff, 0x04);
+	MKRKEY256(rkeys, 7, 0xaa, 0x00);
+	MKRKEY256(rkeys, 8, 0xff, 0x08);
+	MKRKEY256(rkeys, 9, 0xaa, 0x00);
+	MKRKEY256(rkeys, 10, 0xff, 0x10);
+	MKRKEY256(rkeys, 11, 0xaa, 0x00);
+	MKRKEY256(rkeys, 12, 0xff, 0x20);
+	MKRKEY256(rkeys, 13, 0xaa, 0x00);
+	MKRKEY256(rkeys, 14, 0xff, 0x40);
+}
+
+/**
+ * crypto_aes_key_expand_aesni(key, len):
+ * Expand the ${len}-byte AES key ${key} into a structure which can be passed
+ * to crypto_aes_encrypt_block_aesni.  The length must be 16 or 32.  This
+ * implementation uses x86 AESNI instructions, and should only be used if
+ * CPUSUPPORT_X86_AESNI is defined and cpusupport_x86_aesni() returns nonzero.
+ */
+void *
+crypto_aes_key_expand_aesni(const uint8_t * key, size_t len)
+{
+	struct crypto_aes_key_aesni * kexp;
+	size_t rkey_offset;
+
+	/* Allocate structure. */
+	if ((kexp = malloc(sizeof(struct crypto_aes_key_aesni))) == NULL)
+		goto err0;
+
+	/* Figure out where to put the round keys. */
+	rkey_offset = (uintptr_t)(&kexp->rkeys_buf[0]) % sizeof(__m128i);
+	rkey_offset = (sizeof(__m128i) - rkey_offset) % sizeof(__m128i);
+	kexp->rkeys = (void *)&kexp->rkeys_buf[rkey_offset];
+
+	/* Compute round keys. */
+	if (len == 16) {
+		kexp->nr = 10;
+		crypto_aes_key_expand_128_aesni(key, kexp->rkeys);
+	} else if (len == 32) {
+		kexp->nr = 14;
+		crypto_aes_key_expand_256_aesni(key, kexp->rkeys);
+	} else {
+		warn0("Unsupported AES key length: %zu bytes", len);
+		goto err1;
+	}
+
+	/* Success! */
+	return (kexp);
+
+err1:
+	free(kexp);
+err0:
+	/* Failure! */
+	return (NULL);
+}
+
+/**
+ * crypto_aes_encrypt_block_aesni(in, out, key):
+ * Using the expanded AES key ${key}, encrypt the block ${in} and write the
+ * resulting ciphertext to ${out}.  This implementation uses x86 AESNI
+ * instructions, and should only be used if CPUSUPPORT_X86_AESNI is defined
+ * and cpusupport_x86_aesni() returns nonzero.
+ */
+void
+crypto_aes_encrypt_block_aesni(const uint8_t * in, uint8_t * out,
+    const void * key)
+{
+	const struct crypto_aes_key_aesni * _key = key;
+	const __m128i * aes_key = _key->rkeys;
+	__m128i aes_state;
+	size_t nr = _key->nr;
+
+	aes_state = _mm_loadu_si128((const __m128i *)in);
+	aes_state = _mm_xor_si128(aes_state, aes_key[0]);
+	aes_state = _mm_aesenc_si128(aes_state, aes_key[1]);
+	aes_state = _mm_aesenc_si128(aes_state, aes_key[2]);
+	aes_state = _mm_aesenc_si128(aes_state, aes_key[3]);
+	aes_state = _mm_aesenc_si128(aes_state, aes_key[4]);
+	aes_state = _mm_aesenc_si128(aes_state, aes_key[5]);
+	aes_state = _mm_aesenc_si128(aes_state, aes_key[6]);
+	aes_state = _mm_aesenc_si128(aes_state, aes_key[7]);
+	aes_state = _mm_aesenc_si128(aes_state, aes_key[8]);
+	aes_state = _mm_aesenc_si128(aes_state, aes_key[9]);
+	if (nr > 10) {
+		aes_state = _mm_aesenc_si128(aes_state, aes_key[10]);
+		aes_state = _mm_aesenc_si128(aes_state, aes_key[11]);
+
+		if (nr > 12) {
+			aes_state = _mm_aesenc_si128(aes_state, aes_key[12]);
+			aes_state = _mm_aesenc_si128(aes_state, aes_key[13]);
+		}
+	}
+
+	aes_state = _mm_aesenclast_si128(aes_state, aes_key[nr]);
+	_mm_storeu_si128((__m128i *)out, aes_state);
+}
+
+/**
+ * crypto_aes_key_free_aesni(key):
+ * Free the expanded AES key ${key}.
+ */
+void
+crypto_aes_key_free_aesni(void * key)
+{
+
+	/* Behave consistently with free(NULL). */
+	if (key == NULL)
+		return;
+
+	/* Attempt to zero the expanded key. */
+	insecure_memzero(key, sizeof(struct crypto_aes_key_aesni));
+
+	/* Free the key. */
+	free(key);
+}
+
+#endif /* CPUSUPPORT_X86_AESNI */
diff -pruN 0.8.0-0.3/scrypt-1.2.1/libcperciva/crypto/crypto_aes_aesni.h 0.8.20-1/scrypt-1.2.1/libcperciva/crypto/crypto_aes_aesni.h
--- 0.8.0-0.3/scrypt-1.2.1/libcperciva/crypto/crypto_aes_aesni.h	1970-01-01 00:00:00.000000000 +0000
+++ 0.8.20-1/scrypt-1.2.1/libcperciva/crypto/crypto_aes_aesni.h	2022-02-21 10:55:27.000000000 +0000
@@ -0,0 +1,31 @@
+#ifndef _CRYPTO_AES_AESNI_H_
+#define _CRYPTO_AES_AESNI_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+/**
+ * crypto_aes_key_expand_aesni(key, len):
+ * Expand the ${len}-byte AES key ${key} into a structure which can be passed
+ * to crypto_aes_encrypt_block_aesni.  The length must be 16 or 32.  This
+ * implementation uses x86 AESNI instructions, and should only be used if
+ * CPUSUPPORT_X86_AESNI is defined and cpusupport_x86_aesni() returns nonzero.
+ */
+void * crypto_aes_key_expand_aesni(const uint8_t *, size_t);
+
+/**
+ * crypto_aes_encrypt_block_aesni(in, out, key):
+ * Using the expanded AES key ${key}, encrypt the block ${in} and write the
+ * resulting ciphertext to ${out}.  This implementation uses x86 AESNI
+ * instructions, and should only be used if CPUSUPPORT_X86_AESNI is defined
+ * and cpusupport_x86_aesni() returns nonzero.
+ */
+void crypto_aes_encrypt_block_aesni(const uint8_t *, uint8_t *, const void *);
+
+/**
+ * crypto_aes_key_free_aesni(key):
+ * Free the expanded AES key ${key}.
+ */
+void crypto_aes_key_free_aesni(void *);
+
+#endif /* !_CRYPTO_AES_AESNI_H_ */
diff -pruN 0.8.0-0.3/scrypt-1.2.1/libcperciva/crypto/crypto_aes.c 0.8.20-1/scrypt-1.2.1/libcperciva/crypto/crypto_aes.c
--- 0.8.0-0.3/scrypt-1.2.1/libcperciva/crypto/crypto_aes.c	1970-01-01 00:00:00.000000000 +0000
+++ 0.8.20-1/scrypt-1.2.1/libcperciva/crypto/crypto_aes.c	2022-02-21 10:55:27.000000000 +0000
@@ -0,0 +1,173 @@
+#include <assert.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <openssl/aes.h>
+
+#include "cpusupport.h"
+#include "crypto_aes_aesni.h"
+#include "insecure_memzero.h"
+#include "warnp.h"
+
+#include "crypto_aes.h"
+
+/**
+ * This represents either an AES_KEY or a struct crypto_aes_key_aesni; we
+ * know which it is based on whether we're using AESNI code or not.  As such,
+ * it's just an opaque pointer; but declaring it as a named structure type
+ * prevents type-mismatch bugs in upstream code.
+ */
+struct crypto_aes_key;
+
+#ifdef CPUSUPPORT_X86_AESNI
+/* Test whether OpenSSL and AESNI code produce the same AES ciphertext. */
+static int
+aesnitest(uint8_t ptext[16], uint8_t * key, size_t len)
+{
+	AES_KEY kexp_openssl;
+	void * kexp_aesni;
+	uint8_t ctext_openssl[16];
+	uint8_t ctext_aesni[16];
+
+	/* Sanity-check. */
+	assert((len == 16) || (len == 32));
+
+	/* Expand the key. */
+	AES_set_encrypt_key(key, (int)(len * 8), &kexp_openssl);
+	if ((kexp_aesni = crypto_aes_key_expand_aesni(key, len)) == NULL)
+		goto err0;
+
+	/* Encrypt the block. */
+	AES_encrypt(ptext, ctext_openssl, &kexp_openssl);
+	crypto_aes_encrypt_block_aesni(ptext, ctext_aesni, kexp_aesni);
+
+	/* Free the AESNI expanded key. */
+	crypto_aes_key_free_aesni(kexp_aesni);
+
+	/* Do the outputs match? */
+	return (memcmp(ctext_openssl, ctext_aesni, 16));
+
+err0:
+	/* Failure! */
+	return (-1);
+}
+
+/* Should we use AESNI? */
+static int
+useaesni(void)
+{
+	static int aesnigood = -1;
+	uint8_t key[32];
+	uint8_t ptext[16];
+	size_t i;
+
+	/* If we haven't decided which code to use yet, decide now. */
+	while (aesnigood == -1) {
+		/* Default to OpenSSL. */
+		aesnigood = 0;
+
+		/* If the CPU doesn't claim to support AESNI, stop here. */
+		if (!cpusupport_x86_aesni())
+			break;
+
+		/* Test cases: key is 0x00010203..., ptext is 0x00112233... */
+		for (i = 0; i < 16; i++)
+			ptext[i] = (0x11 * i) & 0xff;
+		for (i = 0; i < 32; i++)
+			key[i] = i & 0xff;
+
+		/* Test that AESNI and OpenSSL produce the same results. */
+		if (aesnitest(ptext, key, 16) || aesnitest(ptext, key, 32)) {
+			warn0("Disabling AESNI due to failed self-test");
+			break;
+		}
+
+		/* AESNI works; use it. */
+		aesnigood = 1;
+	}
+
+	return (aesnigood);
+}
+#endif /* CPUSUPPORT_X86_AESNI */
+
+/**
+ * crypto_aes_key_expand(key, len):
+ * Expand the ${len}-byte AES key ${key} into a structure which can be passed
+ * to crypto_aes_encrypt_block.  The length must be 16 or 32.
+ */
+struct crypto_aes_key *
+crypto_aes_key_expand(const uint8_t * key, size_t len)
+{
+	AES_KEY * kexp;
+
+	/* Sanity-check. */
+	assert((len == 16) || (len == 32));
+
+#ifdef CPUSUPPORT_X86_AESNI
+	/* Use AESNI if we can. */
+	if (useaesni())
+		return (crypto_aes_key_expand_aesni(key, len));
+#endif
+
+	/* Allocate structure. */
+	if ((kexp = malloc(sizeof(AES_KEY))) == NULL)
+		goto err0;
+
+	/* Expand the key. */
+	AES_set_encrypt_key(key, (int)(len * 8), kexp);
+
+	/* Success! */
+	return ((void *)kexp);
+
+err0:
+	/* Failure! */
+	return (NULL);
+}
+
+/**
+ * crypto_aes_encrypt_block(in, out, key):
+ * Using the expanded AES key ${key}, encrypt the block ${in} and write the
+ * resulting ciphertext to ${out}.
+ */
+void
+crypto_aes_encrypt_block(const uint8_t * in, uint8_t * out,
+    const struct crypto_aes_key * key)
+{
+
+#ifdef CPUSUPPORT_X86_AESNI
+	if (useaesni()) {
+		crypto_aes_encrypt_block_aesni(in, out, (const void *)key);
+		return;
+	}
+#endif
+
+	/* Get AES to do the work. */
+	AES_encrypt(in, out, (const void *)key);
+}
+
+/**
+ * crypto_aes_key_free(key):
+ * Free the expanded AES key ${key}.
+ */
+void
+crypto_aes_key_free(struct crypto_aes_key * key)
+{
+
+#ifdef CPUSUPPORT_X86_AESNI
+	if (useaesni()) {
+		crypto_aes_key_free_aesni((void *)key);
+		return;
+	}
+#endif
+
+	/* Behave consistently with free(NULL). */
+	if (key == NULL)
+		return;
+
+	/* Attempt to zero the expanded key. */
+	insecure_memzero(key, sizeof(AES_KEY));
+
+	/* Free the key. */
+	free(key);
+}
diff -pruN 0.8.0-0.3/scrypt-1.2.1/libcperciva/crypto/crypto_aesctr.c 0.8.20-1/scrypt-1.2.1/libcperciva/crypto/crypto_aesctr.c
--- 0.8.0-0.3/scrypt-1.2.1/libcperciva/crypto/crypto_aesctr.c	1970-01-01 00:00:00.000000000 +0000
+++ 0.8.20-1/scrypt-1.2.1/libcperciva/crypto/crypto_aesctr.c	2022-02-21 10:55:27.000000000 +0000
@@ -0,0 +1,119 @@
+#include <stdint.h>
+#include <stdlib.h>
+
+#include "crypto_aes.h"
+#include "insecure_memzero.h"
+#include "sysendian.h"
+
+#include "crypto_aesctr.h"
+
+struct crypto_aesctr {
+	const struct crypto_aes_key * key;
+	uint64_t nonce;
+	uint64_t bytectr;
+	uint8_t buf[16];
+};
+
+/**
+ * crypto_aesctr_init(key, nonce):
+ * Prepare to encrypt/decrypt data with AES in CTR mode, using the provided
+ * expanded key and nonce.  The key provided must remain valid for the
+ * lifetime of the stream.
+ */
+struct crypto_aesctr *
+crypto_aesctr_init(const struct crypto_aes_key * key, uint64_t nonce)
+{
+	struct crypto_aesctr * stream;
+
+	/* Allocate memory. */
+	if ((stream = malloc(sizeof(struct crypto_aesctr))) == NULL)
+		goto err0;
+
+	/* Initialize values. */
+	stream->key = key;
+	stream->nonce = nonce;
+	stream->bytectr = 0;
+
+	/* Success! */
+	return (stream);
+
+err0:
+	/* Failure! */
+	return (NULL);
+}
+
+/**
+ * crypto_aesctr_stream(stream, inbuf, outbuf, buflen):
+ * Generate the next ${buflen} bytes of the AES-CTR stream and xor them with
+ * bytes from ${inbuf}, writing the result into ${outbuf}.  If the buffers
+ * ${inbuf} and ${outbuf} overlap, they must be identical.
+ */
+void
+crypto_aesctr_stream(struct crypto_aesctr * stream, const uint8_t * inbuf,
+    uint8_t * outbuf, size_t buflen)
+{
+	uint8_t pblk[16];
+	size_t pos;
+	int bytemod;
+
+	for (pos = 0; pos < buflen; pos++) {
+		/* How far through the buffer are we? */
+		bytemod = stream->bytectr % 16;
+
+		/* Generate a block of cipherstream if needed. */
+		if (bytemod == 0) {
+			be64enc(pblk, stream->nonce);
+			be64enc(pblk + 8, stream->bytectr / 16);
+			crypto_aes_encrypt_block(pblk, stream->buf,
+			    stream->key);
+		}
+
+		/* Encrypt a byte. */
+		outbuf[pos] = inbuf[pos] ^ stream->buf[bytemod];
+
+		/* Move to the next byte of cipherstream. */
+		stream->bytectr += 1;
+	}
+}
+
+/**
+ * crypto_aesctr_free(stream):
+ * Free the provided stream object.
+ */
+void
+crypto_aesctr_free(struct crypto_aesctr * stream)
+{
+
+	/* Behave consistently with free(NULL). */
+	if (stream == NULL)
+		return;
+
+	/* Zero potentially sensitive information. */
+	insecure_memzero(stream, sizeof(struct crypto_aesctr));
+
+	/* Free the stream. */
+	free(stream);
+}
+
+/**
+ * crypto_aesctr_buf(key, nonce, inbuf, outbuf, buflen):
+ * Equivalent to _init(key, nonce); _stream(inbuf, outbuf, buflen); _free().
+ */
+void
+crypto_aesctr_buf(const struct crypto_aes_key * key, uint64_t nonce,
+    const uint8_t * inbuf, uint8_t * outbuf, size_t buflen)
+{
+	struct crypto_aesctr stream_rec;
+	struct crypto_aesctr * stream = &stream_rec;
+
+	/* Initialize values. */
+	stream->key = key;
+	stream->nonce = nonce;
+	stream->bytectr = 0;
+
+	/* Perform the encryption. */
+	crypto_aesctr_stream(stream, inbuf, outbuf, buflen);
+
+	/* Zero potentially sensitive information. */
+	insecure_memzero(stream, sizeof(struct crypto_aesctr));
+}
diff -pruN 0.8.0-0.3/scrypt-1.2.1/libcperciva/crypto/crypto_aesctr.h 0.8.20-1/scrypt-1.2.1/libcperciva/crypto/crypto_aesctr.h
--- 0.8.0-0.3/scrypt-1.2.1/libcperciva/crypto/crypto_aesctr.h	1970-01-01 00:00:00.000000000 +0000
+++ 0.8.20-1/scrypt-1.2.1/libcperciva/crypto/crypto_aesctr.h	2022-02-21 10:55:27.000000000 +0000
@@ -0,0 +1,42 @@
+#ifndef _CRYPTO_AESCTR_H_
+#define _CRYPTO_AESCTR_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+/* Opaque types. */
+struct crypto_aes_key;
+struct crypto_aesctr;
+
+/**
+ * crypto_aesctr_init(key, nonce):
+ * Prepare to encrypt/decrypt data with AES in CTR mode, using the provided
+ * expanded key and nonce.  The key provided must remain valid for the
+ * lifetime of the stream.
+ */
+struct crypto_aesctr * crypto_aesctr_init(const struct crypto_aes_key *,
+    uint64_t);
+
+/**
+ * crypto_aesctr_stream(stream, inbuf, outbuf, buflen):
+ * Generate the next ${buflen} bytes of the AES-CTR stream and xor them with
+ * bytes from ${inbuf}, writing the result into ${outbuf}.  If the buffers
+ * ${inbuf} and ${outbuf} overlap, they must be identical.
+ */
+void crypto_aesctr_stream(struct crypto_aesctr *, const uint8_t *,
+    uint8_t *, size_t);
+
+/**
+ * crypto_aesctr_free(stream):
+ * Free the provided stream object.
+ */
+void crypto_aesctr_free(struct crypto_aesctr *);
+
+/**
+ * crypto_aesctr_buf(key, nonce, inbuf, outbuf, buflen):
+ * Equivalent to _init(key, nonce); _stream(inbuf, outbuf, buflen); _free().
+ */
+void crypto_aesctr_buf(const struct crypto_aes_key *, uint64_t,
+    const uint8_t *, uint8_t *, size_t);
+
+#endif /* !_CRYPTO_AESCTR_H_ */
diff -pruN 0.8.0-0.3/scrypt-1.2.1/libcperciva/crypto/crypto_aes.h 0.8.20-1/scrypt-1.2.1/libcperciva/crypto/crypto_aes.h
--- 0.8.0-0.3/scrypt-1.2.1/libcperciva/crypto/crypto_aes.h	1970-01-01 00:00:00.000000000 +0000
+++ 0.8.20-1/scrypt-1.2.1/libcperciva/crypto/crypto_aes.h	2022-02-21 10:55:27.000000000 +0000
@@ -0,0 +1,31 @@
+#ifndef _CRYPTO_AES_H_
+#define _CRYPTO_AES_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+/* Opaque structure. */
+struct crypto_aes_key;
+
+/**
+ * crypto_aes_key_expand(key, len):
+ * Expand the ${len}-byte AES key ${key} into a structure which can be passed
+ * to crypto_aes_encrypt_block.  The length must be 16 or 32.
+ */
+struct crypto_aes_key * crypto_aes_key_expand(const uint8_t *, size_t);
+
+/**
+ * crypto_aes_encrypt_block(in, out, key):
+ * Using the expanded AES key ${key}, encrypt the block ${in} and write the
+ * resulting ciphertext to ${out}.
+ */
+void crypto_aes_encrypt_block(const uint8_t *, uint8_t *,
+    const struct crypto_aes_key *);
+
+/**
+ * crypto_aes_key_free(key):
+ * Free the expanded AES key ${key}.
+ */
+void crypto_aes_key_free(struct crypto_aes_key *);
+
+#endif /* !_CRYPTO_AES_H_ */
diff -pruN 0.8.0-0.3/scrypt-1.2.1/libcperciva/crypto/crypto_entropy.c 0.8.20-1/scrypt-1.2.1/libcperciva/crypto/crypto_entropy.c
--- 0.8.0-0.3/scrypt-1.2.1/libcperciva/crypto/crypto_entropy.c	1970-01-01 00:00:00.000000000 +0000
+++ 0.8.20-1/scrypt-1.2.1/libcperciva/crypto/crypto_entropy.c	2022-02-21 10:55:27.000000000 +0000
@@ -0,0 +1,215 @@
+#include <assert.h>
+#include <stdint.h>
+#include <string.h>
+
+#include "entropy.h"
+#include "insecure_memzero.h"
+
+#include "sha256.h"
+
+#include "crypto_entropy.h"
+
+/**
+ * This system implements the HMAC_DRBG pseudo-random number generator as
+ * specified in section 10.1.2 of the NIST SP 800-90 standard.  In this
+ * implementation, the optional personalization_string and additional_input
+ * specified in the standard are not implemented.
+ */
+
+/* Internal HMAC_DRBG state. */
+static struct {
+	uint8_t Key[32];
+	uint8_t V[32];
+	uint32_t reseed_counter;
+} drbg;
+
+/* Set to non-zero once the PRNG has been instantiated. */
+static int instantiated = 0;
+
+/* Could be as high as 2^48 if we wanted... */
+#define RESEED_INTERVAL	256
+
+/* Limited to 2^16 by specification. */
+#define GENERATE_MAXLEN	65536
+
+static int instantiate(void);
+static void update(uint8_t *, size_t);
+static int reseed(void);
+static void generate(uint8_t *, size_t);
+
+/**
+ * instantiate(void):
+ * Initialize the DRBG state.  (Section 10.1.2.3)
+ */
+static int
+instantiate(void)
+{
+	uint8_t seed_material[48];
+
+	/* Obtain random seed_material = (entropy_input || nonce). */
+	if (entropy_read(seed_material, 48))
+		return (-1);
+
+	/* Initialize Key, V, and reseed_counter. */
+	memset(drbg.Key, 0x00, 32);
+	memset(drbg.V, 0x01, 32);
+	drbg.reseed_counter = 1;
+
+	/* Mix the random seed into the state. */
+	update(seed_material, 48);
+
+	/* Clean the stack. */
+	insecure_memzero(seed_material, 48);
+
+	/* Success! */
+	return (0);
+}
+
+/**
+ * update(data, datalen):
+ * Update the DRBG state using the provided data.  (Section 10.1.2.2)
+ */
+static void
+update(uint8_t * data, size_t datalen)
+{
+	HMAC_SHA256_CTX ctx;
+	uint8_t K[32];
+	uint8_t Vx[33];
+
+	/* Load (Key, V) into (K, Vx). */
+	memcpy(K, drbg.Key, 32);
+	memcpy(Vx, drbg.V, 32);
+
+	/* K <- HMAC(K, V || 0x00 || data). */
+	Vx[32] = 0x00;
+	HMAC_SHA256_Init(&ctx, K, 32);
+	HMAC_SHA256_Update(&ctx, Vx, 33);
+	HMAC_SHA256_Update(&ctx, data, datalen);
+	HMAC_SHA256_Final(K, &ctx);
+
+	/* V <- HMAC(K, V). */
+	HMAC_SHA256_Buf(K, 32, Vx, 32, Vx);
+
+	/* If the provided data is non-Null, perform another mixing stage. */
+	if (datalen != 0) {
+		/* K <- HMAC(K, V || 0x01 || data). */
+		Vx[32] = 0x01;
+		HMAC_SHA256_Init(&ctx, K, 32);
+		HMAC_SHA256_Update(&ctx, Vx, 33);
+		HMAC_SHA256_Update(&ctx, data, datalen);
+		HMAC_SHA256_Final(K, &ctx);
+
+		/* V <- HMAC(K, V). */
+		HMAC_SHA256_Buf(K, 32, Vx, 32, Vx);
+	}
+
+	/* Copy (K, Vx) back to (Key, V). */
+	memcpy(drbg.Key, K, 32);
+	memcpy(drbg.V, Vx, 32);
+
+	/* Clean the stack. */
+	insecure_memzero(K, 32);
+	insecure_memzero(Vx, 33);
+}
+
+/**
+ * reseed(void):
+ * Reseed the DRBG state (mix in new entropy).  (Section 10.1.2.4)
+ */
+static int
+reseed(void)
+{
+	uint8_t seed_material[32];
+
+	/* Obtain random seed_material = entropy_input. */
+	if (entropy_read(seed_material, 32))
+		return (-1);
+
+	/* Mix the random seed into the state. */
+	update(seed_material, 32);
+
+	/* Reset the reseed_counter. */
+	drbg.reseed_counter = 1;
+
+	/* Clean the stack. */
+	insecure_memzero(seed_material, 32);
+
+	/* Success! */
+	return (0);
+}
+
+/**
+ * generate(buf, buflen):
+ * Fill the provided buffer with random bits, assuming that reseed_counter
+ * is less than RESEED_INTERVAL (the caller is responsible for calling
+ * reseed() as needed) and ${buflen} is less than 2^16 (the caller is
+ * responsible for splitting up larger requests).  (Section 10.1.2.5)
+ */
+static void
+generate(uint8_t * buf, size_t buflen)
+{
+	size_t bufpos;
+
+	assert(buflen <= GENERATE_MAXLEN);
+	assert(drbg.reseed_counter <= RESEED_INTERVAL);
+
+	/* Iterate until we've filled the buffer. */
+	for (bufpos = 0; bufpos < buflen; bufpos += 32) {
+		HMAC_SHA256_Buf(drbg.Key, 32, drbg.V, 32, drbg.V);
+		if (buflen - bufpos >= 32)
+			memcpy(&buf[bufpos], drbg.V, 32);
+		else
+			memcpy(&buf[bufpos], drbg.V, buflen - bufpos);
+	}
+
+	/* Mix up state. */
+	update(NULL, 0);
+
+	/* We're one data-generation step closer to needing a reseed. */
+	drbg.reseed_counter += 1;
+}
+
+/**
+ * crypto_entropy_read(buf, buflen):
+ * Fill the buffer with unpredictable bits.
+ */
+int
+crypto_entropy_read(uint8_t * buf, size_t buflen)
+{
+	size_t bytes_to_provide;
+
+	/* Instantiate if needed. */
+	if (instantiated == 0) {
+		/* Try to instantiate the PRNG. */
+		if (instantiate())
+			return (-1);
+
+		/* We have instantiated the PRNG. */
+		instantiated = 1;
+	}
+
+	/* Loop until we've filled the buffer. */
+	while (buflen > 0) {
+		/* Do we need to reseed? */
+		if (drbg.reseed_counter > RESEED_INTERVAL) {
+			if (reseed())
+				return (-1);
+		}
+
+		/* How much data are we generating in this step? */
+		if (buflen > GENERATE_MAXLEN)
+			bytes_to_provide = GENERATE_MAXLEN;
+		else
+			bytes_to_provide = buflen;
+
+		/* Generate bytes. */
+		generate(buf, bytes_to_provide);
+
+		/* We've done part of the buffer. */
+		buf += bytes_to_provide;
+		buflen -= bytes_to_provide;
+	}
+
+	/* Success! */
+	return (0);
+}
diff -pruN 0.8.0-0.3/scrypt-1.2.1/libcperciva/crypto/crypto_entropy.h 0.8.20-1/scrypt-1.2.1/libcperciva/crypto/crypto_entropy.h
--- 0.8.0-0.3/scrypt-1.2.1/libcperciva/crypto/crypto_entropy.h	1970-01-01 00:00:00.000000000 +0000
+++ 0.8.20-1/scrypt-1.2.1/libcperciva/crypto/crypto_entropy.h	2022-02-21 10:55:27.000000000 +0000
@@ -0,0 +1,14 @@
+#ifndef _CRYPTO_ENTROPY_H_
+#define _CRYPTO_ENTROPY_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+/**
+ * crypto_entropy_read(buf, buflen):
+ * Fill the buffer with unpredictable bits.  The value ${buflen} must be
+ * less than 2^16.
+ */
+int crypto_entropy_read(uint8_t *, size_t);
+
+#endif /* !_CRYPTO_ENTROPY_H_ */
diff -pruN 0.8.0-0.3/scrypt-1.2.1/libcperciva/util/asprintf.c 0.8.20-1/scrypt-1.2.1/libcperciva/util/asprintf.c
--- 0.8.0-0.3/scrypt-1.2.1/libcperciva/util/asprintf.c	1970-01-01 00:00:00.000000000 +0000
+++ 0.8.20-1/scrypt-1.2.1/libcperciva/util/asprintf.c	2022-02-21 10:55:27.000000000 +0000
@@ -0,0 +1,49 @@
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "asprintf.h"
+
+/**
+ * asprintf(ret, format, ...):
+ * Do asprintf(3) like GNU and BSD do.
+ */
+int
+asprintf(char ** ret, const char * format, ...)
+{
+	va_list ap;
+	int len;
+	size_t buflen;
+
+	/* Figure out how long the string needs to be. */
+	va_start(ap, format);
+	len = vsnprintf(NULL, 0, format, ap);
+	va_end(ap);
+
+	/* Did we fail? */
+	if (len < 0)
+		goto err0;
+	buflen = (size_t)(len) + 1;
+
+	/* Allocate memory. */
+	if ((*ret = malloc(buflen)) == NULL)
+		goto err0;
+
+	/* Actually generate the string. */
+	va_start(ap, format);
+	len = vsnprintf(*ret, buflen, format, ap);
+	va_end(ap);
+
+	/* Did we fail? */
+	if (len < 0)
+		goto err1;
+
+	/* Success! */
+	return (len);
+
+err1:
+	free(*ret);
+err0:
+	/* Failure! */
+	return (-1);
+}
diff -pruN 0.8.0-0.3/scrypt-1.2.1/libcperciva/util/asprintf.h 0.8.20-1/scrypt-1.2.1/libcperciva/util/asprintf.h
--- 0.8.0-0.3/scrypt-1.2.1/libcperciva/util/asprintf.h	1970-01-01 00:00:00.000000000 +0000
+++ 0.8.20-1/scrypt-1.2.1/libcperciva/util/asprintf.h	2022-02-21 10:55:27.000000000 +0000
@@ -0,0 +1,16 @@
+#ifndef _ASPRINTF_H_
+#define _ASPRINTF_H_
+
+/* Avoid namespace collisions with BSD/GNU asprintf. */
+#ifdef asprintf
+#undef asprintf
+#endif
+#define asprintf libcperciva_asprintf
+
+/**
+ * asprintf(ret, format, ...):
+ * Do asprintf(3) like GNU and BSD do.
+ */
+int asprintf(char **, const char *, ...);
+
+#endif /* !_ASPRINTF_H_ */
diff -pruN 0.8.0-0.3/scrypt-1.2.1/libcperciva/util/entropy.c 0.8.20-1/scrypt-1.2.1/libcperciva/util/entropy.c
--- 0.8.0-0.3/scrypt-1.2.1/libcperciva/util/entropy.c	1970-01-01 00:00:00.000000000 +0000
+++ 0.8.20-1/scrypt-1.2.1/libcperciva/util/entropy.c	2022-02-21 10:55:27.000000000 +0000
@@ -0,0 +1,98 @@
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdint.h>
+#include <unistd.h>
+
+#include "warnp.h"
+
+#include "entropy.h"
+
+#ifdef _WIN32
+#include <windows.h>
+#include <Wincrypt.h>
+#define RtlGenRandom SystemFunction036
+BOOLEAN NTAPI RtlGenRandom(PVOID RandomBuffer, ULONG RandomBufferLength);
+#endif
+
+/**
+ * XXX Portability
+ * XXX We obtain random bytes from the operating system by opening
+ * XXX /dev/urandom and reading them from that device; this works on
+ * XXX modern UNIX-like operating systems but not on systems like
+ * XXX win32 where there is no concept of /dev/urandom.
+ */
+
+/**
+ * entropy_read(buf, buflen):
+ * Fill the given buffer with random bytes provided by the operating system.
+ */
+int
+entropy_read(uint8_t * buf, size_t buflen)
+{
+	int fd;
+	ssize_t lenread;
+
+#ifndef _WIN32
+	/* Sanity-check the buffer size. */
+	if (buflen > SSIZE_MAX) {
+		warn0("Programmer error: "
+		    "Trying to read insane amount of random data: %zu",
+		    buflen);
+		goto err0;
+	}
+
+	/* Open /dev/urandom. */
+	if ((fd = open("/dev/urandom", O_RDONLY)) == -1) {
+		warnp("open(/dev/urandom)");
+		goto err0;
+	}
+
+	/* Read bytes until we have filled the buffer. */
+	while (buflen > 0) {
+		if ((lenread = read(fd, buf, buflen)) == -1) {
+			warnp("read(/dev/urandom)");
+			goto err1;
+		}
+
+		/* The random device should never EOF. */
+		if (lenread == 0) {
+			warn0("EOF on /dev/urandom?");
+			goto err1;
+		}
+
+		/* We've filled a portion of the buffer. */
+		buf += (size_t)lenread;
+		buflen -= (size_t)lenread;
+	}
+
+	/* Close the device. */
+	while (close(fd) == -1) {
+		if (errno != EINTR) {
+			warnp("close(/dev/urandom)");
+			goto err0;
+		}
+	}
+
+	/* Success! */
+	return (0);
+
+err1:
+	close(fd);
+err0:
+	/* Failure! */
+	return (-1);
+
+#else // _WIN32
+
+    if(FALSE == RtlGenRandom(buf, buflen))
+    {
+        return (-1);
+    }
+    else{
+		buf += buflen;
+		return(0);
+	}
+
+#endif // _WIN32
+}
diff -pruN 0.8.0-0.3/scrypt-1.2.1/libcperciva/util/entropy.h 0.8.20-1/scrypt-1.2.1/libcperciva/util/entropy.h
--- 0.8.0-0.3/scrypt-1.2.1/libcperciva/util/entropy.h	1970-01-01 00:00:00.000000000 +0000
+++ 0.8.20-1/scrypt-1.2.1/libcperciva/util/entropy.h	2022-02-21 10:55:27.000000000 +0000
@@ -0,0 +1,13 @@
+#ifndef _ENTROPY_H_
+#define _ENTROPY_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+/**
+ * entropy_read(buf, buflen):
+ * Fill the given buffer with random bytes provided by the operating system.
+ */
+int entropy_read(uint8_t *, size_t);
+
+#endif /* !_ENTROPY_H_ */
diff -pruN 0.8.0-0.3/scrypt-1.2.1/libcperciva/util/getopt.c 0.8.20-1/scrypt-1.2.1/libcperciva/util/getopt.c
--- 0.8.0-0.3/scrypt-1.2.1/libcperciva/util/getopt.c	1970-01-01 00:00:00.000000000 +0000
+++ 0.8.20-1/scrypt-1.2.1/libcperciva/util/getopt.c	2022-02-21 10:55:27.000000000 +0000
@@ -0,0 +1,358 @@
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "getopt.h"
+
+/*
+ * Standard getopt global variables.  optreset starts as non-zero in order to
+ * trigger initialization behaviour.
+ */
+const char * optarg = NULL;
+int optind = 1;
+int opterr = 1;
+int optreset = 1;
+
+/*
+ * Quasi-internal global variables -- these are used via GETOPT macros.
+ */
+const char * getopt_dummy = "(dummy)";
+int getopt_initialized = 0;
+
+/*
+ * Internal variables.
+ */
+static const char * cmdname = NULL;
+static struct opt {
+	const char * os;
+	size_t olen;
+	int hasarg;
+} * opts = NULL;
+static size_t nopts;
+static size_t opt_missing;
+static size_t opt_default;
+static size_t opt_found;
+static const char * packedopts;
+static char popt[3];
+static int atexit_registered = 0;
+
+/* Print a message. */
+#define PRINTMSG(...)	do {						\
+	if (cmdname != NULL)						\
+		fprintf(stderr, "%s: ", cmdname);			\
+	fprintf(stderr, __VA_ARGS__);					\
+	fprintf(stderr, "\n");						\
+} while (0)
+
+/* Print an error message and die. */
+#define DIE(...)	do {						\
+	PRINTMSG(__VA_ARGS__);						\
+	abort();							\
+} while (0)
+
+/* Print a warning, if warnings are enabled. */
+#define WARN(...)	do {						\
+	if (opterr == 0)						\
+		break;							\
+	if (opt_missing != opt_default)					\
+		break;							\
+	PRINTMSG(__VA_ARGS__);						\
+} while (0)
+
+/* Free allocated options array. */
+static void
+atexit_handler(void)
+{
+
+	free(opts);
+	opts = NULL;
+}
+
+/* Reset internal state. */
+static void
+reset(int argc, char * const argv[])
+{
+	const char * p;
+
+	/* If we have arguments, stash argv[0] for error messages. */
+	if (argc > 0) {
+		/* Find the basename, without leading directories. */
+		for (p = cmdname = argv[0]; *p != '\0'; p++) {
+			if (*p == '/')
+				cmdname = p + 1;
+		}
+	}
+
+	/* Discard any registered command-line options. */
+	free(opts);
+	opts = NULL;
+
+	/* Register atexit handler if we haven't done so already. */
+	if (!atexit_registered) {
+		atexit(atexit_handler);
+		atexit_registered = 1;
+	}
+
+	/* We will start scanning from the first option. */
+	optind = 1;
+
+	/* We're not in the middle of any packed options. */
+	packedopts = NULL;
+
+	/* We haven't found any option yet. */
+	opt_found = (size_t)(-1);
+
+	/* We're not initialized yet. */
+	getopt_initialized = 0;
+
+	/* Finished resetting state. */
+	optreset = 0;
+}
+
+/* Search for an option string. */
+static size_t
+searchopt(const char * os)
+{
+	size_t i;
+
+	/* Scan the array of options. */
+	for (i = 0; i < nopts; i++) {
+		/* Is there an option in this slot? */
+		if (opts[i].os == NULL)
+			continue;
+
+		/* Does this match up to the length of the option string? */
+		if (strncmp(opts[i].os, os, opts[i].olen))
+			continue;
+
+		/* Do we have <option>\0 or <option>= ? */
+		if ((os[opts[i].olen] == '\0') || (os[opts[i].olen] == '='))
+			return (i);
+	}
+
+	/* Not found. */
+	return (opt_default);
+}
+
+const char *
+getopt(int argc, char * const argv[])
+{
+	const char * os = NULL;
+	const char * canonical_os = NULL;
+
+	/* No argument yet. */
+	optarg = NULL;
+
+	/* Reset the getopt state if needed. */
+	if (optreset)
+		reset(argc, argv);
+
+	/* If not initialized, return dummy option. */
+	if (!getopt_initialized)
+		return (GETOPT_DUMMY);
+
+	/* If we've run out of arguments, we're done. */
+	if (optind >= argc)
+		return (NULL);
+
+	/*
+	 * If we're not already in the middle of a packed single-character
+	 * options, see if we should start.
+	 */
+	if ((packedopts == NULL) && (argv[optind][0] == '-') &&
+	    (argv[optind][1] != '-') && (argv[optind][1] != '\0')) {
+		/* We have one or more single-character options. */
+		packedopts = &argv[optind][1];
+	}
+
+	/* If we're processing single-character options, fish one out. */
+	if (packedopts != NULL) {
+		/* Construct the option string. */
+		popt[0] = '-';
+		popt[1] = *packedopts;
+		popt[2] = '\0';
+		os = popt;
+
+		/* We've done this character. */
+		packedopts++;
+
+		/* Are we done with this string? */
+		if (*packedopts == '\0') {
+			packedopts = NULL;
+			optind++;
+		}
+	}
+
+	/* If we don't have an option yet, do we have dash-dash? */
+	if ((os == NULL) && (argv[optind][0] == '-') &&
+	    (argv[optind][1] == '-')) {
+		/* If this is not "--\0", it's an option. */
+		if (argv[optind][2] != '\0')
+			os = argv[optind];
+
+		/* Either way, we want to eat the string. */
+		optind++;
+	}
+
+	/* If we have found nothing which looks like an option, we're done. */
+	if (os == NULL)
+		return (NULL);
+
+	/* Search for the potential option. */
+	opt_found = searchopt(os);
+
+	/* If the option is not registered, give up now. */
+	if (opt_found == opt_default) {
+		WARN("unknown option: %s", os);
+		return (os);
+	}
+
+	/* The canonical option string is the one registered. */
+	canonical_os = opts[opt_found].os;
+
+	/* Does the option take an argument? */
+	if (opts[opt_found].hasarg) {
+		/*
+		 * If we're processing packed single-character options, the
+		 * rest of the string is the argument to this option.
+		 */
+		if (packedopts != NULL) {
+			optarg = packedopts;
+			packedopts = NULL;
+			optind++;
+		}
+
+		/*
+		 * If the option string is <option>=<value>, extract that
+		 * value as the option argument.
+		 */
+		if (os[opts[opt_found].olen] == '=')
+			optarg = &os[opts[opt_found].olen + 1];
+
+		/*
+		 * If we don't have an argument yet, take one from the
+		 * remaining command line.
+		 */
+		if ((optarg == NULL) && (optind < argc))
+			optarg = argv[optind++];
+
+		/* If we still have no option, declare it MIA. */
+		if (optarg == NULL) {
+			WARN("option requires an argument: %s",
+			    opts[opt_found].os);
+			opt_found = opt_missing;
+		}
+	} else {
+		/* If we have --foo=bar, something went wrong. */
+		if (os[opts[opt_found].olen] == '=') {
+			WARN("option doesn't take an argument: %s",
+			    opts[opt_found].os);
+			opt_found = opt_default;
+		}
+	}
+
+	/* Return the canonical option string. */
+	return (canonical_os);
+}
+
+size_t
+getopt_lookup(const char * os)
+{
+
+	/* Can't reset here. */
+	if (optreset)
+		DIE("Can't reset in the middle of getopt loop");
+
+	/* We should only be called after initialization is complete. */
+	assert(getopt_initialized);
+
+	/* GETOPT_DUMMY should never get passed back to us. */
+	assert(os != GETOPT_DUMMY);
+
+	/*
+	 * Make sure the option passed back to us corresponds to the one we
+	 * found earlier.
+	 */
+	assert((opt_found == opt_missing) || (opt_found == opt_default) ||
+	    ((opt_found < nopts) && (strcmp(os, opts[opt_found].os) == 0)));
+
+	/* Return the option number we identified earlier. */
+	return (opt_found);
+}
+
+void
+getopt_register_opt(const char * os, size_t ln, int hasarg)
+{
+
+	/* Can't reset here. */
+	if (optreset)
+		DIE("Can't reset in the middle of getopt loop");
+
+	/* We should only be called during initialization. */
+	assert(!getopt_initialized);
+
+	/* We should have space allocated for registering options. */
+	assert(opts != NULL);
+
+	/* We should not have registered an option here yet. */
+	assert(opts[ln].os == NULL);
+
+	/* Options should be "-X" or "--foo". */
+	if ((os[0] != '-') || (os[1] == '\0') ||
+	    ((os[1] == '-') && (os[2] == '\0')) ||
+	    ((os[1] != '-') && (os[2] != '\0')))
+		DIE("Not a valid command-line option: %s", os);
+
+	/* Make sure we haven't already registered this option. */
+	if (searchopt(os) != opt_default)
+		DIE("Command-line option registered twice: %s", os);
+
+	/* Record option. */
+	opts[ln].os = os;
+	opts[ln].olen = strlen(os);
+	opts[ln].hasarg = hasarg;
+}
+
+void
+getopt_register_missing(size_t ln)
+{
+
+	/* Can't reset here. */
+	if (optreset)
+		DIE("Can't reset in the middle of getopt loop");
+
+	/* We should only be called during initialization. */
+	assert(!getopt_initialized);
+
+	/* Record missing-argument value. */
+	opt_missing = ln;
+}
+
+void
+getopt_setrange(size_t ln)
+{
+	size_t i;
+
+	/* Can't reset here. */
+	if (optreset)
+		DIE("Can't reset in the middle of getopt loop");
+
+	/* We should only be called during initialization. */
+	assert(!getopt_initialized);
+
+	/* Allocate space for options. */
+	opts = malloc(ln * sizeof(struct opt));
+	if ((ln > 0) && (opts == NULL))
+		DIE("Failed to allocate memory in getopt");
+
+	/* Initialize options. */
+	for (i = 0; i < ln; i++)
+		opts[i].os = NULL;
+
+	/* Record the number of (potential) options. */
+	nopts = ln;
+
+	/* Record default missing-argument and no-such-option values. */
+	opt_missing = opt_default = ln + 1;
+}
diff -pruN 0.8.0-0.3/scrypt-1.2.1/libcperciva/util/getopt.h 0.8.20-1/scrypt-1.2.1/libcperciva/util/getopt.h
--- 0.8.0-0.3/scrypt-1.2.1/libcperciva/util/getopt.h	1970-01-01 00:00:00.000000000 +0000
+++ 0.8.20-1/scrypt-1.2.1/libcperciva/util/getopt.h	2022-02-21 10:55:27.000000000 +0000
@@ -0,0 +1,175 @@
+#ifndef _GETOPT_H_
+#define _GETOPT_H_
+
+#include <setjmp.h>
+#include <stddef.h>
+
+/**
+ * This getopt implementation parses options of the following forms:
+ * -a -b -c foo		(single-character options)
+ * -abc foo		(packed single-character options)
+ * -abcfoo		(packed single-character options and an argument)
+ * --foo bar		(long option)
+ * --foo=bar		(long option and argument separated by '=')
+ *
+ * It does not support abbreviated options (e.g., interpreting --foo as
+ * --foobar when there are no other --foo* options) since that misfeature
+ * results in breakage when new options are added.  It also does not support
+ * options appearing after non-options (e.g., "cp foo bar -R") since that is
+ * a horrible GNU perversion.
+ */
+
+/* Work around LLVM bug. */
+#ifdef __clang__
+#warning Working around bug in LLVM optimizer
+#warning For more details see https://llvm.org/bugs/show_bug.cgi?id=27190
+#define DO_SETJMP _DO_SETJMP(__LINE__)
+#define _DO_SETJMP(x) __DO_SETJMP(x)
+#define __DO_SETJMP(x)							\
+	void * getopt_initloop = && getopt_initloop_ ## x;		\
+	getopt_initloop_ ## x:
+#define DO_LONGJMP							\
+	goto *getopt_initloop
+#else
+#define DO_SETJMP							\
+	sigjmp_buf getopt_initloop;					\
+	if (!getopt_initialized)					\
+		sigsetjmp(getopt_initloop, 0)
+#define DO_LONGJMP							\
+	siglongjmp(getopt_initloop, 1)
+#endif
+
+/* Avoid namespace collisions with libc getopt. */
+#define getopt	libcperciva_getopt
+#define optarg	libcperciva_optarg
+#define optind	libcperciva_optind
+#define opterr	libcperciva_opterr
+#define optreset	libcperciva_optreset
+
+/* Standard getopt global variables. */
+extern const char * optarg;
+extern int optind, opterr, optreset;
+
+/* Dummy option string, equal to "(dummy)". */
+#define GETOPT_DUMMY getopt_dummy
+
+/**
+ * GETOPT(argc, argv):
+ * When called for the first time (or the first time after optreset is set to
+ * a nonzero value), return GETOPT_DUMMY, aka. "(dummy)".  Thereafter, return
+ * the next option string and set optarg / optind appropriately; abort if not
+ * properly initialized when not being called for the first time.
+ */
+#define GETOPT(argc, argv) getopt(argc, argv)
+
+/**
+ * GETOPT_SWITCH(ch):
+ * Jump to the appropriate GETOPT_OPT, GETOPT_OPTARG, GETOPT_MISSING_ARG, or
+ * GETOPT_DEFAULT based on the option string ${ch}.  When called for the first
+ * time, perform magic to index the options.
+ *
+ * GETOPT_SWITCH(ch) is equivalent to "switch (ch)" in a standard getopt loop.
+ */
+#define GETOPT_SWITCH(ch)						\
+	volatile size_t getopt_ln_min = __LINE__;			\
+	volatile size_t getopt_ln = getopt_ln_min - 1;		\
+	volatile int getopt_default_missing = 0;			\
+	DO_SETJMP;						\
+	switch (getopt_initialized ? getopt_lookup(ch) + getopt_ln_min : getopt_ln++)
+
+/**
+ * GETOPT_OPT(os):
+ * Jump to this point when the option string ${os} is passed to GETOPT_SWITCH.
+ *
+ * GETOPT_OPT("-x") is equivalent to "case 'x'" in a standard getopt loop
+ * which has an optstring containing "x".
+ */
+#define GETOPT_OPT(os)	_GETOPT_OPT(os, __LINE__)
+#define _GETOPT_OPT(os, ln)	__GETOPT_OPT(os, ln)
+#define __GETOPT_OPT(os, ln)						\
+	case ln:							\
+		if (getopt_initialized)					\
+			goto getopt_skip_ ## ln;			\
+		getopt_register_opt(os, ln - getopt_ln_min, 0);		\
+		DO_LONGJMP;						\
+	getopt_skip_ ## ln
+
+/**
+ * GETOPT_OPTARG(os):
+ * Jump to this point when the option string ${os} is passed to GETOPT_SWITCH,
+ * unless no argument is available, in which case jump to GETOPT_MISSING_ARG
+ * (if present) or GETOPT_DEFAULT (if not).
+ *
+ * GETOPT_OPTARG("-x") is equivalent to "case 'x'" in a standard getopt loop
+ * which has an optstring containing "x:".
+ */
+#define GETOPT_OPTARG(os)	_GETOPT_OPTARG(os, __LINE__)
+#define _GETOPT_OPTARG(os, ln)	__GETOPT_OPTARG(os, ln)
+#define __GETOPT_OPTARG(os, ln)						\
+	case ln:							\
+		if (getopt_initialized)					\
+			goto getopt_skip_ ## ln;			\
+		getopt_register_opt(os, ln - getopt_ln_min, 1);		\
+		DO_LONGJMP;						\
+	getopt_skip_ ## ln
+
+/**
+ * GETOPT_MISSING_ARG:
+ * Jump to this point if an option string specified in GETOPT_OPTARG is seen
+ * but no argument is available.
+ *
+ * GETOPT_MISSING_ARG is equivalent to "case ':'" in a standard getopt loop
+ * which has an optstring starting with ":".  As such, it also has the effect
+ * of disabling warnings about invalid options, as if opterr had been zeroed.
+ */
+#define GETOPT_MISSING_ARG	_GETOPT_MISSING_ARG(__LINE__)
+#define _GETOPT_MISSING_ARG(ln)	__GETOPT_MISSING_ARG(ln)
+#define __GETOPT_MISSING_ARG(ln)					\
+	case ln:							\
+		if (getopt_initialized)					\
+			goto getopt_skip_ ## ln;			\
+		getopt_register_missing(ln - getopt_ln_min);		\
+		DO_LONGJMP;						\
+	getopt_skip_ ## ln
+
+/**
+ * GETOPT_DEFAULT:
+ * Jump to this point if an unrecognized option is seen or if an option
+ * specified in GETOPT_OPTARG is seen, no argument is available, and there is
+ * no GETOPT_MISSING_ARG label.
+ *
+ * GETOPT_DEFAULT is equivalent to "case '?'" in a standard getopt loop.
+ *
+ * NOTE: This MUST be present in the GETOPT_SWITCH statement, and MUST occur
+ * after all other GETOPT_* labels.
+ */
+#define GETOPT_DEFAULT		_GETOPT_DEFAULT(__LINE__)
+#define _GETOPT_DEFAULT(ln)	__GETOPT_DEFAULT(ln)
+#define __GETOPT_DEFAULT(ln)						\
+		goto getopt_skip_ ## ln;				\
+	case ln:							\
+		getopt_initialized = 1;					\
+		break;							\
+	default:							\
+		if (getopt_initialized)					\
+			goto getopt_skip_ ## ln;			\
+		if (!getopt_default_missing) {				\
+			getopt_setrange(ln - getopt_ln_min);		\
+			getopt_default_missing = 1;			\
+		}							\
+		DO_LONGJMP;						\
+	getopt_skip_ ## ln
+
+/*
+ * The back-end implementation.  These should be considered internal
+ * interfaces and not used directly.
+ */
+const char * getopt(int, char * const []);
+size_t getopt_lookup(const char *);
+void getopt_register_opt(const char *, size_t, int);
+void getopt_register_missing(size_t);
+void getopt_setrange(size_t);
+extern const char * getopt_dummy;
+extern int getopt_initialized;
+
+#endif /* !_GETOPT_H_ */
diff -pruN 0.8.0-0.3/scrypt-1.2.1/libcperciva/util/humansize.c 0.8.20-1/scrypt-1.2.1/libcperciva/util/humansize.c
--- 0.8.0-0.3/scrypt-1.2.1/libcperciva/util/humansize.c	1970-01-01 00:00:00.000000000 +0000
+++ 0.8.20-1/scrypt-1.2.1/libcperciva/util/humansize.c	2022-02-21 10:55:27.000000000 +0000
@@ -0,0 +1,165 @@
+#include <stdio.h>
+
+#include "asprintf.h"
+#include "warnp.h"
+
+#include "humansize.h"
+
+/**
+ * humansize(size):
+ * Given a size in bytes, allocate and return a string of the form "<N> B"
+ * for 0 <= N <= 999 or "<X> <prefix>B" where either 10 <= X <= 999 or
+ * 1.0 <= X <= 9.9 and <prefix> is "k", "M", "G", "T", "P", or "E"; and where
+ * the value returned is the largest valid value <= the provided size.
+ */
+char *
+humansize(uint64_t size)
+{
+	char * s;
+	char prefix;
+	int shiftcnt;
+	int rc;
+
+	/* Special-case for size < 1000. */
+	if (size < 1000) {
+		rc = asprintf(&s, "%d B", (int)size);
+	} else {
+		/* Keep 10 * size / 1000^(3n) in size. */
+		for (size /= 100, shiftcnt = 1; size >= 10000; shiftcnt++)
+			size /= 1000;
+
+		/*
+		 * Figure out what prefix to use.  Since 1 EB = 10^18 B and
+		 * the maximum value of a uint64_t is 2^64 which is roughly
+		 * 18.4 * 10^18, this cannot reference beyond the end of the
+		 * string.
+		 */
+		prefix = " kMGTPE"[shiftcnt];
+
+		/* Construct the string. */
+		if (size < 100)
+			rc = asprintf(&s, "%d.%d %cB", (int)size / 10,
+			    (int)size % 10, prefix);
+		else
+			rc = asprintf(&s, "%d %cB", (int)size / 10, prefix);
+	}
+
+	if (rc == -1) {
+		warnp("asprintf");
+		goto err0;
+	}
+
+	/* Success! */
+	return (s);
+
+err0:
+	/* Failure! */
+	return (NULL);
+}
+
+/**
+ * humansize_parse(s, size):
+ * Parse a string matching /[0-9]+ ?[kMGTPE]?B?/ as a size in bytes.
+ */
+int
+humansize_parse(const char * s, uint64_t * size)
+{
+	int state = 0;
+	uint64_t multiplier = 1;
+
+	do {
+		switch (state) {
+		case -1:
+			/* Error state. */
+			break;
+		case 0:
+			/* Initial state. */
+			*size = 0;
+
+			/* We must start with at least one digit. */
+			if ((*s < '0') || (*s > '9')) {
+				state = -1;
+				break;
+			}
+
+			/* FALLTHROUGH */
+		case 1:
+			/* We're now processing digits. */
+			state = 1;
+
+			/* Digit-parsing state. */
+			if (('0' <= *s) && (*s <= '9')) {
+				if (*size > UINT64_MAX / 10)
+					state = -1;
+				else
+					*size *= 10;
+				if (*size > UINT64_MAX - (uint64_t)(*s - '0'))
+					state = -1;
+				else
+					*size += (uint64_t)(*s - '0');
+				break;
+			}
+
+			/* FALLTHROUGH */
+		case 2:
+			/* We move into state 3 after an optional ' '. */
+			state = 3;
+			if (*s == ' ')
+				break;
+
+			/* FALLTHROUGH */
+		case 3:
+			/* We may have one SI prefix. */
+			switch (*s) {
+			case 'E':
+				multiplier *= 1000;
+				/* FALLTHROUGH */
+			case 'P':
+				multiplier *= 1000;
+				/* FALLTHROUGH */
+			case 'T':
+				multiplier *= 1000;
+				/* FALLTHROUGH */
+			case 'G':
+				multiplier *= 1000;
+				/* FALLTHROUGH */
+			case 'M':
+				multiplier *= 1000;
+				/* FALLTHROUGH */
+			case 'k':
+				multiplier *= 1000;
+				break;
+			}
+
+			/* We move into state 4 after the optional prefix. */
+			state = 4;
+			if (multiplier != 1)
+				break;
+
+			/* FALLTHROUGH */
+		case 4:
+			/* We move into state 5 after an optional 'B'. */
+			state = 5;
+			if (*s == 'B')
+				break;
+
+			/* FALLTHROUGH */
+		case 5:
+			/* We have trailing garbage. */
+			state = -1;
+			break;
+		}
+
+		/* Move on to the next character. */
+		s++;
+	} while (*s != '\0');
+
+	/* Multiply by multiplier. */
+	if (*size > UINT64_MAX / multiplier)
+		state = -1;
+	else
+		*size *= multiplier;
+
+	/* Anything other than state -1 is success. */
+	return ((state == -1) ? -1 : 0);
+}
diff -pruN 0.8.0-0.3/scrypt-1.2.1/libcperciva/util/humansize.h 0.8.20-1/scrypt-1.2.1/libcperciva/util/humansize.h
--- 0.8.0-0.3/scrypt-1.2.1/libcperciva/util/humansize.h	1970-01-01 00:00:00.000000000 +0000
+++ 0.8.20-1/scrypt-1.2.1/libcperciva/util/humansize.h	2022-02-21 10:55:27.000000000 +0000
@@ -0,0 +1,21 @@
+#ifndef _HUMANSIZE_H_
+#define _HUMANSIZE_H_
+
+#include <stdint.h>
+
+/**
+ * humansize(size):
+ * Given a size in bytes, allocate and return a string of the form "<N> B"
+ * for 0 <= N <= 999 or "<X> <prefix>B" where either 10 <= X <= 999 or
+ * 1.0 <= X <= 9.9 and <prefix> is "k", "M", "G", "T", "P", or "E"; and where
+ * the value returned is the largest valid value <= the provided size.
+ */
+char * humansize(uint64_t);
+
+/**
+ * humansize_parse(s, size):
+ * Parse a string matching /[0-9]+ ?[kMGTPE]?B?/ as a size in bytes.
+ */
+int humansize_parse(const char *, uint64_t *);
+
+#endif /* !_HUMANSIZE_H_ */
diff -pruN 0.8.0-0.3/scrypt-1.2.1/libcperciva/util/insecure_memzero.c 0.8.20-1/scrypt-1.2.1/libcperciva/util/insecure_memzero.c
--- 0.8.0-0.3/scrypt-1.2.1/libcperciva/util/insecure_memzero.c	1970-01-01 00:00:00.000000000 +0000
+++ 0.8.20-1/scrypt-1.2.1/libcperciva/util/insecure_memzero.c	2022-02-21 10:55:27.000000000 +0000
@@ -0,0 +1,19 @@
+#include <stddef.h>
+#include <stdint.h>
+
+#include "insecure_memzero.h"
+
+/* Function which does the zeroing. */
+static void
+insecure_memzero_func(volatile void * buf, size_t len)
+{
+	volatile uint8_t * _buf = buf;
+	size_t i;
+
+	for (i = 0; i < len; i++)
+		_buf[i] = 0;
+}
+
+/* Pointer to memory-zeroing function. */
+void (* volatile insecure_memzero_ptr)(volatile void *, size_t) =
+    insecure_memzero_func;
diff -pruN 0.8.0-0.3/scrypt-1.2.1/libcperciva/util/insecure_memzero.h 0.8.20-1/scrypt-1.2.1/libcperciva/util/insecure_memzero.h
--- 0.8.0-0.3/scrypt-1.2.1/libcperciva/util/insecure_memzero.h	1970-01-01 00:00:00.000000000 +0000
+++ 0.8.20-1/scrypt-1.2.1/libcperciva/util/insecure_memzero.h	2022-02-21 10:55:27.000000000 +0000
@@ -0,0 +1,37 @@
+#ifndef _INSECURE_MEMZERO_H_
+#define _INSECURE_MEMZERO_H_
+
+#include <stddef.h>
+
+/* Pointer to memory-zeroing function. */
+extern void (* volatile insecure_memzero_ptr)(volatile void *, size_t);
+
+/**
+ * insecure_memzero(buf, len):
+ * Attempt to zero ${len} bytes at ${buf} in spite of optimizing compilers'
+ * best (standards-compliant) attempts to remove the buffer-zeroing.  In
+ * particular, to avoid performing the zeroing, a compiler would need to
+ * use optimistic devirtualization; recognize that non-volatile objects do not
+ * need to be treated as volatile, even if they are accessed via volatile
+ * qualified pointers; and perform link-time optimization; in addition to the
+ * dead-code elimination which often causes buffer-zeroing to be elided.
+ *
+ * Note however that zeroing a buffer does not guarantee that the data held
+ * in the buffer is not stored elsewhere; in particular, there may be copies
+ * held in CPU registers or in anonymous allocations on the stack, even if
+ * every named variable is successfully sanitized.  Solving the "wipe data
+ * from the system" problem will require a C language extension which does not
+ * yet exist.
+ *
+ * For more information, see:
+ * http://www.daemonology.net/blog/2014-09-04-how-to-zero-a-buffer.html
+ * http://www.daemonology.net/blog/2014-09-06-zeroing-buffers-is-insufficient.html
+ */
+static inline void
+insecure_memzero(volatile void * buf, size_t len)
+{
+
+	(insecure_memzero_ptr)(buf, len);
+}
+
+#endif /* !_INSECURE_MEMZERO_H_ */
diff -pruN 0.8.0-0.3/scrypt-1.2.1/libcperciva/util/readpass.c 0.8.20-1/scrypt-1.2.1/libcperciva/util/readpass.c
--- 0.8.0-0.3/scrypt-1.2.1/libcperciva/util/readpass.c	1970-01-01 00:00:00.000000000 +0000
+++ 0.8.20-1/scrypt-1.2.1/libcperciva/util/readpass.c	2022-02-21 10:55:27.000000000 +0000
@@ -0,0 +1,202 @@
+#include <signal.h>
+#include <stdio.h>
+#include <string.h>
+#include <termios.h>
+#include <unistd.h>
+
+#include "insecure_memzero.h"
+#include "warnp.h"
+
+#include "readpass.h"
+
+#define MAXPASSLEN 2048
+
+/* Signals we need to block. */
+static const int badsigs[] = {
+	SIGALRM, SIGHUP, SIGINT,
+	SIGPIPE, SIGQUIT, SIGTERM,
+	SIGTSTP, SIGTTIN, SIGTTOU
+};
+#define NSIGS sizeof(badsigs)/sizeof(badsigs[0])
+
+/* Highest signal number we care about. */
+#define MAX2(a, b) ((a) > (b) ? (a) : (b))
+#define MAX4(a, b, c, d) MAX2(MAX2(a, b), MAX2(c, d))
+#define MAX8(a, b, c, d, e, f, g, h) MAX2(MAX4(a, b, c, d), MAX4(e, f, g, h))
+#define MAXBADSIG	MAX2(SIGALRM, MAX8(SIGHUP, SIGINT, SIGPIPE, SIGQUIT, \
+			    SIGTERM, SIGTSTP, SIGTTIN, SIGTTOU))
+
+/* Has a signal of this type been received? */
+static volatile sig_atomic_t gotsig[MAXBADSIG + 1];
+
+/* Signal handler. */
+static void
+handle(int sig)
+{
+
+	gotsig[sig] = 1;
+}
+
+/* Restore old signals and re-issue intercepted signals. */
+static void
+resetsigs(struct sigaction savedsa[NSIGS])
+{
+	size_t i;
+
+	/* Restore old signals. */
+	for (i = 0; i < NSIGS; i++)
+		sigaction(badsigs[i], &savedsa[i], NULL);
+
+	/* If we intercepted a signal, re-issue it. */
+	for (i = 0; i < NSIGS; i++) {
+		if (gotsig[badsigs[i]])
+			raise(badsigs[i]);
+	}
+}
+
+/**
+ * readpass(passwd, prompt, confirmprompt, devtty)
+ * If ${devtty} is non-zero, read a password from /dev/tty if possible; if
+ * not, read from stdin.  If reading from a tty (either /dev/tty or stdin),
+ * disable echo and prompt the user by printing ${prompt} to stderr.  If
+ * ${confirmprompt} is non-NULL, read a second password (prompting if a
+ * terminal is being used) and repeat until the user enters the same password
+ * twice.  Return the password as a malloced NUL-terminated string via
+ * ${passwd}.
+ */
+int
+readpass(char ** passwd, const char * prompt,
+    const char * confirmprompt, int devtty)
+{
+	FILE * readfrom;
+	char passbuf[MAXPASSLEN];
+	char confpassbuf[MAXPASSLEN];
+	struct sigaction sa, savedsa[NSIGS];
+	struct termios term, term_old;
+	size_t i;
+	int usingtty;
+
+	/*
+	 * If devtty != 0, try to open /dev/tty; if that fails, or if devtty
+	 * is zero, we'll read the password from stdin instead.
+	 */
+	if ((devtty == 0) || ((readfrom = fopen("/dev/tty", "r")) == NULL))
+		readfrom = stdin;
+
+	/* We have not received any signals yet. */
+	for (i = 0; i <= MAXBADSIG; i++)
+		gotsig[i] = 0;
+
+	/*
+	 * If we receive a signal while we're reading the password, we might
+	 * end up with echo disabled; to prevent this, we catch the signals
+	 * here, and we'll re-send them to ourselves later after we re-enable
+	 * terminal echo.
+	 */
+	sa.sa_handler = handle;
+	sa.sa_flags = 0;
+	sigemptyset(&sa.sa_mask);
+	for (i = 0; i < NSIGS; i++)
+		sigaction(badsigs[i], &sa, &savedsa[i]);
+
+	/* If we're reading from a terminal, try to disable echo. */
+	if ((usingtty = isatty(fileno(readfrom))) != 0) {
+		if (tcgetattr(fileno(readfrom), &term_old)) {
+			warnp("Cannot read terminal settings");
+			goto err2;
+		}
+		memcpy(&term, &term_old, sizeof(struct termios));
+		term.c_lflag = (term.c_lflag & ~((tcflag_t)ECHO)) | ECHONL;
+		if (tcsetattr(fileno(readfrom), TCSANOW, &term)) {
+			warnp("Cannot set terminal settings");
+			goto err2;
+		}
+	}
+
+retry:
+	/* If we have a terminal, prompt the user to enter the password. */
+	if (usingtty)
+		fprintf(stderr, "%s: ", prompt);
+
+	/* Read the password. */
+	if (fgets(passbuf, MAXPASSLEN, readfrom) == NULL) {
+		if (feof(readfrom))
+			warn0("EOF reading password");
+		else
+			warnp("Cannot read password");
+		goto err3;
+	}
+
+	/* Confirm the password if necessary. */
+	if (confirmprompt != NULL) {
+		if (usingtty)
+			fprintf(stderr, "%s: ", confirmprompt);
+		if (fgets(confpassbuf, MAXPASSLEN, readfrom) == NULL) {
+			if (feof(readfrom))
+				warn0("EOF reading password");
+			else
+				warnp("Cannot read password");
+			goto err3;
+		}
+		if (strcmp(passbuf, confpassbuf)) {
+			fprintf(stderr,
+			    "Passwords mismatch, please try again\n");
+			goto retry;
+		}
+	}
+
+	/* Terminate the string at the first "\r" or "\n" (if any). */
+	passbuf[strcspn(passbuf, "\r\n")] = '\0';
+
+	/* If we changed terminal settings, reset them. */
+	if (usingtty)
+		tcsetattr(fileno(readfrom), TCSANOW, &term_old);
+
+	/* Restore old signals and re-issue intercepted signals. */
+	resetsigs(savedsa);
+
+	/* Close /dev/tty if we opened it. */
+	if (readfrom != stdin)
+		fclose(readfrom);
+
+	/* Copy the password out. */
+	if ((*passwd = strdup(passbuf)) == NULL) {
+		warnp("Cannot allocate memory");
+		goto err1;
+	}
+
+	/*
+	 * Zero any stored passwords.  This is not guaranteed to work, since a
+	 * "sufficiently intelligent" compiler can optimize these out due to
+	 * the values not being accessed again; and even if we outwitted the
+	 * compiler, all we can do is ensure that *a* buffer is zeroed but
+	 * not that it is the only buffer containing the data in question.
+	 * Unfortunately the C standard does not provide any way to mark data
+	 * as "sensitive" in order to prevent extra copies being sprinkled
+	 * around the implementation address space.
+	 */
+	insecure_memzero(passbuf, MAXPASSLEN);
+	insecure_memzero(confpassbuf, MAXPASSLEN);
+
+	/* Success! */
+	return (0);
+
+err3:
+	/* Reset terminal settings if necessary. */
+	if (usingtty)
+		tcsetattr(fileno(readfrom), TCSAFLUSH, &term_old);
+err2:
+	/* Close /dev/tty if we opened it. */
+	if (readfrom != stdin)
+		fclose(readfrom);
+
+	/* Restore old signals and re-issue intercepted signals. */
+	resetsigs(savedsa);
+err1:
+	/* Zero any stored passwords. */
+	insecure_memzero(passbuf, MAXPASSLEN);
+	insecure_memzero(confpassbuf, MAXPASSLEN);
+
+	/* Failure! */
+	return (-1);
+}
diff -pruN 0.8.0-0.3/scrypt-1.2.1/libcperciva/util/readpass.h 0.8.20-1/scrypt-1.2.1/libcperciva/util/readpass.h
--- 0.8.0-0.3/scrypt-1.2.1/libcperciva/util/readpass.h	1970-01-01 00:00:00.000000000 +0000
+++ 0.8.20-1/scrypt-1.2.1/libcperciva/util/readpass.h	2022-02-21 10:55:27.000000000 +0000
@@ -0,0 +1,22 @@
+#ifndef _READPASS_H_
+#define _READPASS_H_
+
+/* Avoid namespace collisions with other "readpass" functions. */
+#ifdef readpass
+#undef readpass
+#endif
+#define readpass libcperciva_readpass
+
+/**
+ * readpass(passwd, prompt, confirmprompt, devtty)
+ * If ${devtty} is non-zero, read a password from /dev/tty if possible; if
+ * not, read from stdin.  If reading from a tty (either /dev/tty or stdin),
+ * disable echo and prompt the user by printing ${prompt} to stderr.  If
+ * ${confirmprompt} is non-NULL, read a second password (prompting if a
+ * terminal is being used) and repeat until the user enters the same password
+ * twice.  Return the password as a malloced NUL-terminated string via
+ * ${passwd}.
+ */
+int readpass(char **, const char *, const char *, int);
+
+#endif /* !_READPASS_H_ */
diff -pruN 0.8.0-0.3/scrypt-1.2.1/libcperciva/util/sysendian.h 0.8.20-1/scrypt-1.2.1/libcperciva/util/sysendian.h
--- 0.8.0-0.3/scrypt-1.2.1/libcperciva/util/sysendian.h	1970-01-01 00:00:00.000000000 +0000
+++ 0.8.20-1/scrypt-1.2.1/libcperciva/util/sysendian.h	2022-02-21 10:55:27.000000000 +0000
@@ -0,0 +1,146 @@
+#ifndef _SYSENDIAN_H_
+#define _SYSENDIAN_H_
+
+#include <stdint.h>
+
+/* Avoid namespace collisions with BSD <sys/endian.h>. */
+#define be16dec libcperciva_be16dec
+#define be16enc libcperciva_be16enc
+#define be32dec libcperciva_be32dec
+#define be32enc libcperciva_be32enc
+#define be64dec libcperciva_be64dec
+#define be64enc libcperciva_be64enc
+#define le16dec libcperciva_le16dec
+#define le16enc libcperciva_le16enc
+#define le32dec libcperciva_le32dec
+#define le32enc libcperciva_le32enc
+#define le64dec libcperciva_le64dec
+#define le64enc libcperciva_le64enc
+
+static inline uint16_t
+be16dec(const void * pp)
+{
+	const uint8_t * p = (uint8_t const *)pp;
+
+	return (uint16_t)((uint16_t)(p[1]) + ((uint16_t)(p[0]) << 8));
+}
+
+static inline void
+be16enc(void * pp, uint16_t x)
+{
+	uint8_t * p = (uint8_t *)pp;
+
+	p[1] = x & 0xff;
+	p[0] = (x >> 8) & 0xff;
+}
+
+static inline uint32_t
+be32dec(const void * pp)
+{
+	const uint8_t * p = (uint8_t const *)pp;
+
+	return ((uint32_t)(p[3]) + ((uint32_t)(p[2]) << 8) +
+	    ((uint32_t)(p[1]) << 16) + ((uint32_t)(p[0]) << 24));
+}
+
+static inline void
+be32enc(void * pp, uint32_t x)
+{
+	uint8_t * p = (uint8_t *)pp;
+
+	p[3] = x & 0xff;
+	p[2] = (x >> 8) & 0xff;
+	p[1] = (x >> 16) & 0xff;
+	p[0] = (x >> 24) & 0xff;
+}
+
+static inline uint64_t
+be64dec(const void * pp)
+{
+	const uint8_t * p = (uint8_t const *)pp;
+
+	return ((uint64_t)(p[7]) + ((uint64_t)(p[6]) << 8) +
+	    ((uint64_t)(p[5]) << 16) + ((uint64_t)(p[4]) << 24) +
+	    ((uint64_t)(p[3]) << 32) + ((uint64_t)(p[2]) << 40) +
+	    ((uint64_t)(p[1]) << 48) + ((uint64_t)(p[0]) << 56));
+}
+
+static inline void
+be64enc(void * pp, uint64_t x)
+{
+	uint8_t * p = (uint8_t *)pp;
+
+	p[7] = x & 0xff;
+	p[6] = (x >> 8) & 0xff;
+	p[5] = (x >> 16) & 0xff;
+	p[4] = (x >> 24) & 0xff;
+	p[3] = (x >> 32) & 0xff;
+	p[2] = (x >> 40) & 0xff;
+	p[1] = (x >> 48) & 0xff;
+	p[0] = (x >> 56) & 0xff;
+}
+
+static inline uint16_t
+le16dec(const void * pp)
+{
+	const uint8_t * p = (uint8_t const *)pp;
+
+	return (uint16_t)((uint16_t)(p[0]) + ((uint16_t)(p[1]) << 8));
+}
+
+static inline void
+le16enc(void * pp, uint16_t x)
+{
+	uint8_t * p = (uint8_t *)pp;
+
+	p[0] = x & 0xff;
+	p[1] = (x >> 8) & 0xff;
+}
+
+static inline uint32_t
+le32dec(const void * pp)
+{
+	const uint8_t * p = (uint8_t const *)pp;
+
+	return ((uint32_t)(p[0]) + ((uint32_t)(p[1]) << 8) +
+	    ((uint32_t)(p[2]) << 16) + ((uint32_t)(p[3]) << 24));
+}
+
+static inline void
+le32enc(void * pp, uint32_t x)
+{
+	uint8_t * p = (uint8_t *)pp;
+
+	p[0] = x & 0xff;
+	p[1] = (x >> 8) & 0xff;
+	p[2] = (x >> 16) & 0xff;
+	p[3] = (x >> 24) & 0xff;
+}
+
+static inline uint64_t
+le64dec(const void * pp)
+{
+	const uint8_t * p = (uint8_t const *)pp;
+
+	return ((uint64_t)(p[0]) + ((uint64_t)(p[1]) << 8) +
+	    ((uint64_t)(p[2]) << 16) + ((uint64_t)(p[3]) << 24) +
+	    ((uint64_t)(p[4]) << 32) + ((uint64_t)(p[5]) << 40) +
+	    ((uint64_t)(p[6]) << 48) + ((uint64_t)(p[7]) << 56));
+}
+
+static inline void
+le64enc(void * pp, uint64_t x)
+{
+	uint8_t * p = (uint8_t *)pp;
+
+	p[0] = x & 0xff;
+	p[1] = (x >> 8) & 0xff;
+	p[2] = (x >> 16) & 0xff;
+	p[3] = (x >> 24) & 0xff;
+	p[4] = (x >> 32) & 0xff;
+	p[5] = (x >> 40) & 0xff;
+	p[6] = (x >> 48) & 0xff;
+	p[7] = (x >> 56) & 0xff;
+}
+
+#endif /* !_SYSENDIAN_H_ */
diff -pruN 0.8.0-0.3/scrypt-1.2.1/libcperciva/util/warnp.c 0.8.20-1/scrypt-1.2.1/libcperciva/util/warnp.c
--- 0.8.0-0.3/scrypt-1.2.1/libcperciva/util/warnp.c	1970-01-01 00:00:00.000000000 +0000
+++ 0.8.20-1/scrypt-1.2.1/libcperciva/util/warnp.c	2022-02-21 10:55:27.000000000 +0000
@@ -0,0 +1,76 @@
+#include <errno.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "warnp.h"
+
+static int initialized = 0;
+static char * name = NULL;
+
+/* Free the name string. */
+static void
+done(void)
+{
+
+	free(name);
+	name = NULL;
+}
+
+/**
+ * warnp_setprogname(progname):
+ * Set the program name to be used by warn() and warnx() to ${progname}.
+ */
+void
+warnp_setprogname(const char * progname)
+{
+	const char * p;
+
+	/* Free the name if we already have one. */
+	free(name);
+
+	/* Find the last segment of the program name. */
+	for (p = progname; progname[0] != '\0'; progname++)
+		if (progname[0] == '/')
+			p = progname + 1;
+
+	/* Copy the name string. */
+	name = strdup(p);
+
+	/* If we haven't already done so, register our exit handler. */
+	if (initialized == 0) {
+		atexit(done);
+		initialized = 1;
+	}
+}
+
+void
+warn(const char * fmt, ...)
+{
+	va_list ap;
+
+	va_start(ap, fmt);
+	fprintf(stderr, "%s", (name != NULL) ? name : "(unknown)");
+	if (fmt != NULL) {
+		fprintf(stderr, ": ");
+		vfprintf(stderr, fmt, ap);
+	}
+	fprintf(stderr, ": %s\n", strerror(errno));
+	va_end(ap);
+}
+
+void
+warnx(const char * fmt, ...)
+{
+	va_list ap;
+
+	va_start(ap, fmt);
+	fprintf(stderr, "%s", (name != NULL) ? name : "(unknown)");
+	if (fmt != NULL) {
+		fprintf(stderr, ": ");
+		vfprintf(stderr, fmt, ap);
+	}
+	fprintf(stderr, "\n");
+	va_end(ap);
+}
diff -pruN 0.8.0-0.3/scrypt-1.2.1/libcperciva/util/warnp.h 0.8.20-1/scrypt-1.2.1/libcperciva/util/warnp.h
--- 0.8.0-0.3/scrypt-1.2.1/libcperciva/util/warnp.h	1970-01-01 00:00:00.000000000 +0000
+++ 0.8.20-1/scrypt-1.2.1/libcperciva/util/warnp.h	2022-02-21 10:55:27.000000000 +0000
@@ -0,0 +1,60 @@
+#ifndef _WARNP_H_
+#define _WARNP_H_
+
+#include <errno.h>
+#include <stddef.h>
+
+/* Avoid namespace collisions with BSD <err.h>. */
+#define warn libcperciva_warn
+#define warnx libcperciva_warnx
+
+/**
+ * warnp_setprogname(progname):
+ * Set the program name to be used by warn() and warnx() to ${progname}.
+ */
+void warnp_setprogname(const char *);
+#define WARNP_INIT	do {		\
+	if (argv[0] != NULL)		\
+		warnp_setprogname(argv[0]);	\
+} while (0)
+
+/* As in BSD <err.h>. */
+void warn(const char *, ...);
+void warnx(const char *, ...);
+
+/*
+ * If compiled with DEBUG defined, print __FILE__ and __LINE__.
+ */
+#ifdef DEBUG
+#define warnline	do {				\
+	warnx("%s, %d", __FILE__, __LINE__);	\
+} while (0)
+#else
+#define warnline
+#endif
+
+/*
+ * Call warn(3) or warnx(3) depending upon whether errno == 0; and clear
+ * errno (so that the standard error message isn't repeated later).
+ */
+#define	warnp(...) do {					\
+	warnline;					\
+	if (errno != 0) {				\
+		warn(__VA_ARGS__);		\
+		errno = 0;				\
+	} else						\
+		warnx(__VA_ARGS__);		\
+} while (0)
+
+/*
+ * Call warnx(3) and set errno == 0.  Unlike warnp, this should be used
+ * in cases where we're reporting a problem which we discover ourselves
+ * rather than one which is reported to us from a library or the kernel.
+ */
+#define warn0(...) do {					\
+	warnline;					\
+	warnx(__VA_ARGS__);			\
+	errno = 0;					\
+} while (0)
+
+#endif /* !_WARNP_H_ */
diff -pruN 0.8.0-0.3/scrypt-1.2.1/README.md 0.8.20-1/scrypt-1.2.1/README.md
--- 0.8.0-0.3/scrypt-1.2.1/README.md	1970-01-01 00:00:00.000000000 +0000
+++ 0.8.20-1/scrypt-1.2.1/README.md	2022-02-21 10:55:27.000000000 +0000
@@ -0,0 +1,143 @@
+The scrypt key derivation function
+----------------------------------
+
+
+The scrypt key derivation function was originally developed for use in the
+[Tarsnap online backup system](http://www.tarsnap.com/index.html) and is
+designed to be far more secure against hardware brute-force attacks than
+alternative functions such as [PBKDF2](http://en.wikipedia.org/wiki/PBKDF2) or
+[bcrypt](http://www.openbsd.org/papers/bcrypt-paper.ps).
+
+We estimate that on modern (2009) hardware, if 5 seconds are spent computing a
+derived key, the cost of a hardware brute-force attack against `scrypt` is
+roughly 4000 times greater than the cost of a similar attack against bcrypt (to
+find the same password), and 20000 times greater than a similar attack against
+PBKDF2.
+
+Details of the `scrypt` key derivation function are given in a paper which was
+presented at the [BSDCan'09](http://www.bsdcan.org/2009/) conference:
+
+* Colin Percival, [Stronger Key Derivation via Sequential Memory-Hard
+  Functions](http://www.tarsnap.com/scrypt/scrypt.pdf), presented at BSDCan'09,
+  May 2009.
+* Conference presentation slides:
+  [PDF](http://www.tarsnap.com/scrypt/scrypt-slides.pdf).
+
+More details are given in the Internet Engineering Task Force
+(IETF)
+[RFC 7914: The scrypt Password-Based Key Derivation Function](https://tools.ietf.org/html/rfc7914).
+
+It has been demonstrated that scrypt is maximally memory-hard:
+
+* J. Alwen, B. Chen, K. Pietrzak, L. Reyzin, S. Tessaro,
+  [Scrypt is Maximally Memory-Hard](http://eprint.iacr.org/2016/989),
+  Cryptology ePrint Archive: Report 2016/989.
+
+
+The scrypt encryption utility
+-----------------------------
+
+A simple password-based encryption utility is available as a demonstration of
+the `scrypt` key derivation function. On modern hardware and with default
+parameters, the cost of cracking the password on a file encrypted by `scrypt
+enc` is approximately 100 billion times more than the cost of cracking the same
+password on a file encrypted by `openssl enc`; this means that a five-character
+password using `scrypt` is stronger than a ten-character password using
+`openssl`.
+
+The `scrypt` utility can be invoked as `scrypt enc infile [outfile]` to encrypt
+data (if `outfile` is not specified, the encrypted data is written to the
+standard output), or as `scrypt dec infile [outfile]` to decrypt data (if
+outfile is not specified, the decrypted data is written to the standard
+output). `scrypt` also supports three command-line options:
+
+* `-t maxtime` will instruct `scrypt` to spend at most maxtime seconds
+  computing the derived encryption key from the password; for encryption, this
+  value will determine how secure the encrypted data is, while for decryption
+  this value is used as an upper limit (if `scrypt` detects that it would take
+  too long to decrypt the data, it will exit with an error message).
+* `-m maxmemfrac` instructs `scrypt` to use at most the specified fraction of
+  the available RAM for computing the derived encryption key. For encryption,
+  increasing this value might increase the security of the encrypted data,
+  depending on the `maxtime` value; for decryption, this value is used as an
+  upper limit and may `cause` scrypt to exit with an error.
+* `-M maxmem` instructs `scrypt` to use at most the specified number of bytes
+  of RAM when computing the derived encryption key.
+
+If the encrypted data is corrupt, `scrypt dec` will exit with a non-zero
+status.  However, **`scrypt dec` may produce output before it determines that
+the encrypted data was corrupt**, so for applications which require data to be
+authenticated, you must store the output of `scrypt dec` in a temporary
+location and check `scrypt`'s exit code before using the decrypted data.
+
+The `scrypt` utility has been tested on FreeBSD, NetBSD, OpenBSD, Linux
+(Slackware, CentOS, Gentoo, Ubuntu), Solaris, OS X, Cygwin, and GNU Hurd. To
+build scrypt, extract the tarball and run `./configure` && `make`.
+
+* [scrypt version 1.2.0 source
+  tarball](https://www.tarsnap.com/scrypt/scrypt-1.2.0.tgz)
+* [GPG-signed SHA256 for scrypt version
+  1.2.0](https://www.tarsnap.com/scrypt/scrypt-sigs-1.2.0.asc) (signature
+  generated using Tarsnap [code signing
+  key](https://www.tarsnap.com/tarsnap-signing-key.asc))
+
+In addition, `scrypt` is available in the OpenBSD and FreeBSD ports trees and
+in NetBSD pkgsrc as `security/scrypt`.
+
+
+Using scrypt as a KDF
+---------------------
+
+To use scrypt as a
+[key derivation function](https://en.wikipedia.org/wiki/Key_derivation_function)
+(KDF), take a
+look at the `lib/crypto/crypto_scrypt.h` header, which provides:
+
+```
+/**
+ * crypto_scrypt(passwd, passwdlen, salt, saltlen, N, r, p, buf, buflen):
+ * Compute scrypt(passwd[0 .. passwdlen - 1], salt[0 .. saltlen - 1], N, r,
+ * p, buflen) and write the result into buf.  The parameters r, p, and buflen
+ * must satisfy r * p < 2^30 and buflen <= (2^32 - 1) * 32.  The parameter N
+ * must be a power of 2 greater than 1.
+ *
+ * Return 0 on success; or -1 on error.
+ */
+int crypto_scrypt(const uint8_t *, size_t, const uint8_t *, size_t, uint64_t,
+    uint32_t, uint32_t, uint8_t *, size_t);
+```
+
+
+Building
+--------
+
+:exclamation: We strongly recommend that people use the latest
+official release tarball on https://www.tarsnap.com/scrypt.html
+
+See the `BUILDING` file for more details (e.g., dealing with OpenSSL on OSX).
+
+
+Testing
+-------
+
+A small test suite can be run with:
+
+    make test
+
+Memory-testing normal operations with valgrind (takes approximately 4 times as
+long as no valgrind tests) can be enabled with:
+
+    make test USE_VALGRIND=1
+
+Memory-testing all tests with valgrind (requires over 1 GB memory, and takes
+approximately 4 times as long as `USE_VALGRIND=1`) can be enabled with:
+
+    make test USE_VALGRIND=2
+
+
+Mailing list
+------------
+
+The scrypt key derivation function and the scrypt encryption utility are
+discussed on the <scrypt@tarsnap.com> mailing list.
+
diff -pruN 0.8.0-0.3/scrypt-1.2.1/scrypt_platform.h 0.8.20-1/scrypt-1.2.1/scrypt_platform.h
--- 0.8.0-0.3/scrypt-1.2.1/scrypt_platform.h	1970-01-01 00:00:00.000000000 +0000
+++ 0.8.20-1/scrypt-1.2.1/scrypt_platform.h	2022-02-21 10:55:27.000000000 +0000
@@ -0,0 +1,12 @@
+#ifndef _SCRYPT_PLATFORM_H_
+#define	_SCRYPT_PLATFORM_H_
+
+#if defined(CONFIG_H_FILE)
+#include CONFIG_H_FILE
+#elif defined(HAVE_CONFIG_H)
+#include "config.h"
+#else
+#error Need either CONFIG_H_FILE or HAVE_CONFIG_H defined.
+#endif
+
+#endif /* !_SCRYPT_PLATFORM_H_ */
diff -pruN 0.8.0-0.3/scrypt.egg-info/dependency_links.txt 0.8.20-1/scrypt.egg-info/dependency_links.txt
--- 0.8.0-0.3/scrypt.egg-info/dependency_links.txt	2016-09-17 13:30:16.000000000 +0000
+++ 0.8.20-1/scrypt.egg-info/dependency_links.txt	1970-01-01 00:00:00.000000000 +0000
@@ -1 +0,0 @@
-
diff -pruN 0.8.0-0.3/scrypt.egg-info/PKG-INFO 0.8.20-1/scrypt.egg-info/PKG-INFO
--- 0.8.0-0.3/scrypt.egg-info/PKG-INFO	2016-09-17 13:30:16.000000000 +0000
+++ 0.8.20-1/scrypt.egg-info/PKG-INFO	1970-01-01 00:00:00.000000000 +0000
@@ -1,141 +0,0 @@
-Metadata-Version: 1.1
-Name: scrypt
-Version: 0.8.0
-Summary: Bindings for the scrypt key derivation function library
-Home-page: http://bitbucket.org/mhallin/py-scrypt
-Author: Magnus Hallin
-Author-email: mhallin@gmail.com
-License: 2-clause BSD
-Description: =========================
-         Python scrypt_ bindings
-        =========================
-        
-        This is a set of Python_ bindings for the scrypt_ key derivation
-        function.
-        
-        Scrypt is useful when encrypting password as it is possible to specify
-        a *minimum* amount of time to use when encrypting and decrypting. If,
-        for example, a password takes 0.05 seconds to verify, a user won't
-        notice the slight delay when signing in, but doing a brute force
-        search of several billion passwords will take a considerable amount of
-        time. This is in contrast to more traditional hash functions such as
-        MD5 or the SHA family which can be implemented extremely fast on cheap
-        hardware.
-        
-        Installation
-        ============
-        
-        You can install py-scrypt from this repository if you want the latest
-        but possibly non-compiling version::
-        
-            $ hg clone http://bitbucket.org/mhallin/py-scrypt
-            $ cd py-scrypt
-            $ python setup.py build
-        
-            Become superuser (or use virtualenv):
-            # python setup.py install
-        
-            Run tests after install:
-            $ python setup.py test
-        
-        Or you can install the latest release from PyPi::
-        
-            $ pip install scrypt
-        
-        If you want py-scrypt for your Python 3 environment, just run the
-        above commands with your Python 3 interpreter. Py-scrypt supports both
-        Python 2 and 3.
-        
-        From version 0.6.0 (not available on PyPi yet), py-scrypt supports
-        PyPy as well.
-        
-        Usage
-        =====
-        
-        Fore encryption/decryption, the library exports two functions
-        ``encrypt`` and ``decrypt``::
-        
-            >>> import scrypt
-            >>> data = scrypt.encrypt('a secret message', 'password', maxtime=0.1) # This will take at least 0.1 seconds
-            >>> data[:20]
-            'scrypt\x00\r\x00\x00\x00\x08\x00\x00\x00\x01RX9H'
-            >>> scrypt.decrypt(data, 'password', maxtime=0.1) # This will also take at least 0.1 seconds
-            'a secret message'
-            >>> scrypt.decrypt(data, 'password', maxtime=0.05) # scrypt won't be able to decrypt this data fast enough
-            Traceback (most recent call last):
-              File "<stdin>", line 1, in <module>
-            scrypt.error: decrypting file would take too long
-            >>> scrypt.decrypt(data, 'wrong password', maxtime=0.1) # scrypt will throw an exception if the password is incorrect
-            Traceback (most recent call last):
-              File "<stdin>", line 1, in <module>
-            scrypt.error: password is incorrect
-        
-        From these, one can make a simple password verifier using the following
-        functions::
-        
-            def hash_password(password, maxtime=0.5, datalength=64):
-                return scrypt.encrypt(os.urandom(datalength), password, maxtime=maxtime)
-        
-            def verify_password(hashed_password, guessed_password, maxtime=0.5):
-                try:
-                    scrypt.decrypt(hashed_password, guessed_password, maxtime)
-                    return True
-                except scrypt.error:
-                    return False
-        
-        
-        But, if you want output that is deterministic and constant in size,
-        you can use the ``hash`` function::
-        
-            >>> import scrypt
-            >>> h1 = scrypt.hash('password', 'random salt')
-            >>> len(h1)  # The hash will be 64 bytes by default, but is overridable.
-            64
-            >>> h1[:10]
-            '\xfe\x87\xf3hS\tUo\xcd\xc8'
-            >>> h2 = scrypt.hash('password', 'random salt')
-            >>> h1 == h2 # The hash function is deterministic
-            True
-        
-        
-        Acknowledgements
-        ================
-        
-        Scrypt_ was created by Colin Percival and is licensed as 2-clause BSD.
-        Since scrypt does not normally build as a shared library, I have included
-        the source for the currently latest version of the library in this
-        repository. When a new version arrives, I will update these sources.
-        
-        `Kelvin Wong`_ on Bitbucket provided changes to make the library
-        available on Mac OS X 10.6 and earlier, as well as changes to make the
-        library work more like the command-line version of scrypt by
-        default. Kelvin also contributed with the unit tests, lots of cross
-        platform testing and work on the ``hash`` function.
-        
-        Burstaholic_ on Bitbucket provided the necessary changes to make
-        the library build on Windows.
-        
-        The `python-appveyor-demo`_ repository for setting up automated Windows
-        builds for a multitude of Python versions.
-        
-        License
-        =======
-        
-        This library is licensed under the same license as scrypt; 2-clause BSD.
-        
-        .. _scrypt: http://www.tarsnap.com/scrypt.html
-        .. _Python: http://python.org
-        .. _Burstaholic: https://bitbucket.org/Burstaholic
-        .. _Kelvin Wong: https://bitbucket.org/kelvinwong_ca
-        .. _python-appveyor-demo: https://github.com/ogrisel/python-appveyor-demo
-        
-Platform: UNKNOWN
-Classifier: Development Status :: 4 - Beta
-Classifier: Intended Audience :: Developers
-Classifier: License :: OSI Approved :: BSD License
-Classifier: Programming Language :: Python :: 2.7
-Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.4
-Classifier: Programming Language :: Python :: 3.5
-Classifier: Topic :: Security :: Cryptography
-Classifier: Topic :: Software Development :: Libraries
diff -pruN 0.8.0-0.3/scrypt.egg-info/SOURCES.txt 0.8.20-1/scrypt.egg-info/SOURCES.txt
--- 0.8.0-0.3/scrypt.egg-info/SOURCES.txt	2016-09-17 13:30:16.000000000 +0000
+++ 0.8.20-1/scrypt.egg-info/SOURCES.txt	1970-01-01 00:00:00.000000000 +0000
@@ -1,47 +0,0 @@
-MANIFEST.in
-README.rst
-scrypt.py
-setup.py
-scrypt-1.2.0/config.h
-scrypt-1.2.0/scrypt_platform.h
-scrypt-1.2.0/lib/crypto/crypto_scrypt.c
-scrypt-1.2.0/lib/crypto/crypto_scrypt.h
-scrypt-1.2.0/lib/crypto/crypto_scrypt_smix.c
-scrypt-1.2.0/lib/crypto/crypto_scrypt_smix.h
-scrypt-1.2.0/lib/crypto/crypto_scrypt_smix_sse2.c
-scrypt-1.2.0/lib/crypto/crypto_scrypt_smix_sse2.h
-scrypt-1.2.0/lib/scryptenc/scryptenc.c
-scrypt-1.2.0/lib/scryptenc/scryptenc.h
-scrypt-1.2.0/lib/scryptenc/scryptenc_cpuperf.c
-scrypt-1.2.0/lib/scryptenc/scryptenc_cpuperf.h
-scrypt-1.2.0/lib/util/memlimit.c
-scrypt-1.2.0/lib/util/memlimit.h
-scrypt-1.2.0/libcperciva/alg/sha256.c
-scrypt-1.2.0/libcperciva/alg/sha256.h
-scrypt-1.2.0/libcperciva/cpusupport/cpusupport.h
-scrypt-1.2.0/libcperciva/crypto/crypto_aes.c
-scrypt-1.2.0/libcperciva/crypto/crypto_aes.h
-scrypt-1.2.0/libcperciva/crypto/crypto_aes_aesni.c
-scrypt-1.2.0/libcperciva/crypto/crypto_aes_aesni.h
-scrypt-1.2.0/libcperciva/crypto/crypto_aesctr.c
-scrypt-1.2.0/libcperciva/crypto/crypto_aesctr.h
-scrypt-1.2.0/libcperciva/crypto/crypto_entropy.c
-scrypt-1.2.0/libcperciva/crypto/crypto_entropy.h
-scrypt-1.2.0/libcperciva/util/entropy.c
-scrypt-1.2.0/libcperciva/util/entropy.h
-scrypt-1.2.0/libcperciva/util/insecure_memzero.c
-scrypt-1.2.0/libcperciva/util/insecure_memzero.h
-scrypt-1.2.0/libcperciva/util/sysendian.h
-scrypt-1.2.0/libcperciva/util/warnp.c
-scrypt-1.2.0/libcperciva/util/warnp.h
-scrypt.egg-info/PKG-INFO
-scrypt.egg-info/SOURCES.txt
-scrypt.egg-info/dependency_links.txt
-scrypt.egg-info/top_level.txt
-src/scrypt.c
-tests/__init__.py
-tests/ciphertexts.csv
-tests/hashvectors.csv
-tests/test_scrypt.py
-tests/test_scrypt_py2x.py
-tests/test_scrypt_py3x.py
\ No newline at end of file
diff -pruN 0.8.0-0.3/scrypt.egg-info/top_level.txt 0.8.20-1/scrypt.egg-info/top_level.txt
--- 0.8.0-0.3/scrypt.egg-info/top_level.txt	2016-09-17 13:30:16.000000000 +0000
+++ 0.8.20-1/scrypt.egg-info/top_level.txt	1970-01-01 00:00:00.000000000 +0000
@@ -1,2 +0,0 @@
-_scrypt
-scrypt
diff -pruN 0.8.0-0.3/scrypt.py 0.8.20-1/scrypt.py
--- 0.8.0-0.3/scrypt.py	2015-07-05 11:26:08.000000000 +0000
+++ 0.8.20-1/scrypt.py	1970-01-01 00:00:00.000000000 +0000
@@ -1,224 +0,0 @@
-import imp
-import os
-import sys
-
-from ctypes import (cdll,
-                    POINTER, pointer,
-                    c_char_p,
-                    c_size_t, c_double, c_int, c_uint64, c_uint32,
-                    create_string_buffer)
-
-_scrypt = cdll.LoadLibrary(imp.find_module('_scrypt')[1])
-
-_scryptenc_buf = _scrypt.exp_scryptenc_buf
-_scryptenc_buf.argtypes = [c_char_p,  # const uint_t  *inbuf
-                           c_size_t,  # size_t         inbuflen
-                           c_char_p,  # uint8_t       *outbuf
-                           c_char_p,  # const uint8_t *passwd
-                           c_size_t,  # size_t         passwdlen
-                           c_size_t,  # size_t         maxmem
-                           c_double,  # double         maxmemfrac
-                           c_double,  # double         maxtime
-                           ]
-_scryptenc_buf.restype = c_int
-
-_scryptdec_buf = _scrypt.exp_scryptdec_buf
-_scryptdec_buf.argtypes = [c_char_p,           # const uint8_t *inbuf
-                           c_size_t,           # size_t         inbuflen
-                           c_char_p,           # uint8_t       *outbuf
-                           POINTER(c_size_t),  # size_t        *outlen
-                           c_char_p,           # const uint8_t *passwd
-                           c_size_t,           # size_t         passwdlen
-                           c_size_t,           # size_t         maxmem
-                           c_double,           # double         maxmemfrac
-                           c_double,           # double         maxtime
-                           ]
-_scryptdec_buf.restype = c_int
-
-_crypto_scrypt = _scrypt.exp_crypto_scrypt
-_crypto_scrypt.argtypes = [c_char_p,  # const uint8_t *passwd
-                           c_size_t,  # size_t         passwdlen
-                           c_char_p,  # const uint8_t *salt
-                           c_size_t,  # size_t         saltlen
-                           c_uint64,  # uint64_t       N
-                           c_uint32,  # uint32_t       r
-                           c_uint32,  # uint32_t       p
-                           c_char_p,  # uint8_t       *buf
-                           c_size_t,  # size_t         buflen
-                           ]
-_crypto_scrypt.restype = c_int
-
-ERROR_MESSAGES = ['success',
-                  'getrlimit or sysctl(hw.usermem) failed',
-                  'clock_getres or clock_gettime failed',
-                  'error computing derived key',
-                  'could not read salt from /dev/urandom',
-                  'error in OpenSSL',
-                  'malloc failed',
-                  'data is not a valid scrypt-encrypted block',
-                  'unrecognized scrypt format',
-                  'decrypting file would take too much memory',
-                  'decrypting file would take too long',
-                  'password is incorrect',
-                  'error writing output file',
-                  'error reading input file']
-
-MAXMEM_DEFAULT = 0
-MAXMEMFRAC_DEFAULT = 0.5
-MAXTIME_DEFAULT = 300.0
-MAXTIME_DEFAULT_ENC = 5.0
-
-IS_PY2 = sys.version_info < (3, 0, 0, 'final', 0)
-
-
-class error(Exception):
-    def __init__(self, scrypt_code):
-        if isinstance(scrypt_code, int):
-            self._scrypt_code = scrypt_code
-            super(error, self).__init__(ERROR_MESSAGES[scrypt_code])
-        else:
-            self._scrypt_code = -1
-            super(error, self).__init__(scrypt_code)
-
-
-def _ensure_bytes(data):
-    if IS_PY2 and isinstance(data, unicode):
-        raise TypeError('can not encrypt/decrypt unicode objects')
-
-    if not IS_PY2 and isinstance(data, str):
-        return bytes(data, 'utf-8')
-
-    return data
-
-
-def encrypt(input, password,
-            maxtime=MAXTIME_DEFAULT_ENC,
-            maxmem=MAXMEM_DEFAULT,
-            maxmemfrac=MAXMEMFRAC_DEFAULT):
-    """
-    Encrypt a string using a password. The resulting data will have len =
-    len(input) + 128.
-
-    Notes for Python 2:
-      - `input` and `password` must be str instances
-      - The result will be a str instance
-
-    Notes for Python 3:
-      - `input` and `password` can be both str and bytes. If they are str
-        instances, they will be encoded with utf-8
-      - The result will be a bytes instance
-
-    Exceptions raised:
-      - TypeError on invalid input
-      - scrypt.error if encryption failed
-
-    For more information on the `maxtime`, `maxmem`, and `maxmemfrac`
-    parameters, see the scrypt documentation.
-    """
-
-    input = _ensure_bytes(input)
-    password = _ensure_bytes(password)
-
-    outbuf = create_string_buffer(len(input) + 128)
-    result = _scryptenc_buf(input, len(input),
-                            outbuf,
-                            password, len(password),
-                            maxmem, maxmemfrac, maxtime)
-    if result:
-        raise error(result)
-
-    return outbuf.raw
-
-
-def decrypt(input, password,
-            maxtime=MAXTIME_DEFAULT,
-            maxmem=MAXMEM_DEFAULT,
-            maxmemfrac=MAXMEMFRAC_DEFAULT,
-            encoding='utf-8'):
-    """
-    Decrypt a string using a password.
-
-    Notes for Python 2:
-      - `input` and `password` must be str instances
-      - The result will be a str instance
-      - The encoding parameter is ignored
-
-    Notes for Python 3:
-      - `input` and `password` can be both str and bytes. If they are str
-        instances, they wil be encoded with utf-8. `input` *should*
-        really be a bytes instance, since that's what `encrypt` returns.
-      - The result will be a str instance encoded with `encoding`.
-        If encoding=None, the result will be a bytes instance.
-
-    Exceptions raised:
-      - TypeError on invalid input
-      - scrypt.error if decryption failed
-
-    For more information on the `maxtime`, `maxmem`, and `maxmemfrac`
-    parameters, see the scrypt documentation.
-    """
-
-    outbuf = create_string_buffer(len(input))
-    outbuflen = pointer(c_size_t(0))
-
-    input = _ensure_bytes(input)
-    password = _ensure_bytes(password)
-
-    result = _scryptdec_buf(input, len(input),
-                            outbuf, outbuflen,
-                            password, len(password),
-                            maxmem, maxmemfrac, maxtime)
-
-    if result:
-        raise error(result)
-
-    out_bytes = outbuf.raw[:outbuflen.contents.value]
-
-    if IS_PY2 or encoding is None:
-        return out_bytes
-
-    return str(out_bytes, encoding)
-
-
-def hash(password, salt, N=1 << 14, r=8, p=1, buflen=64):
-    """
-    Compute scrypt(password, salt, N, r, p, buflen).
-
-    The parameters r, p, and buflen must satisfy r * p < 2^30 and
-    buflen <= (2^32 - 1) * 32. The parameter N must be a power of 2
-    greater than 1. N, r and p must all be positive.
-
-    Notes for Python 2:
-      - `password` and `salt` must be str instances
-      - The result will be a str instance
-
-    Notes for Python 3:
-      - `password` and `salt` can be both str and bytes. If they are str
-        instances, they wil be encoded with utf-8.
-      - The result will be a bytes instance
-
-    Exceptions raised:
-      - TypeError on invalid input
-      - scrypt.error if scrypt failed
-    """
-
-    outbuf = create_string_buffer(buflen)
-
-    password = _ensure_bytes(password)
-    salt = _ensure_bytes(salt)
-
-    if r * p >= (1 << 30) or N <= 1 or (N & (N - 1)) != 0 or p < 1 or r < 1:
-        raise error('hash parameters are wrong (r*p should be < 2**30, and N should be a power of two > 1)')
-
-    result = _crypto_scrypt(password, len(password),
-                            salt, len(salt),
-                            N, r, p,
-                            outbuf, buflen)
-
-    if result:
-        raise error('could not compute hash')
-
-    return outbuf.raw
-
-
-__all__ = ['error', 'encrypt', 'decrypt', 'hash']
diff -pruN 0.8.0-0.3/scrypt-windows-stubs/gettimeofday.c 0.8.20-1/scrypt-windows-stubs/gettimeofday.c
--- 0.8.0-0.3/scrypt-windows-stubs/gettimeofday.c	1970-01-01 00:00:00.000000000 +0000
+++ 0.8.20-1/scrypt-windows-stubs/gettimeofday.c	2022-02-21 10:55:27.000000000 +0000
@@ -0,0 +1,67 @@
+/*
+ * Copied from PostgreSQL source:
+ *  http://doxygen.postgresql.org/gettimeofday_8c_source.html
+ *
+ */
+
+/*
+ * gettimeofday.c
+ *	  Win32 gettimeofday() replacement
+ *
+ * src/port/gettimeofday.c
+ *
+ * Copyright (c) 2003 SRA, Inc.
+ * Copyright (c) 2003 SKC, Inc.
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose, without fee, and without a
+ * written agreement is hereby granted, provided that the above
+ * copyright notice and this paragraph and the following two
+ * paragraphs appear in all copies.
+ *
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE TO ANY PARTY FOR DIRECT,
+ * INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING
+ * LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS
+ * DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE AUTHOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS
+ * IS" BASIS, AND THE AUTHOR HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE,
+ * SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ */
+
+#ifdef _MSC_VER
+
+#include <winsock2.h>
+
+
+/* FILETIME of Jan 1 1970 00:00:00. */
+static const unsigned __int64 epoch = 116444736000000000Ui64;
+
+/*
+ * timezone information is stored outside the kernel so tzp isn't used anymore.
+ *
+ * Note: this function is not for Win32 high precision timing purpose. See
+ * elapsed_time().
+ */
+int
+gettimeofday(struct timeval * tp, struct timezone * tzp)
+{
+	FILETIME	file_time;
+	SYSTEMTIME	system_time;
+	ULARGE_INTEGER ularge;
+
+	GetSystemTime(&system_time);
+	SystemTimeToFileTime(&system_time, &file_time);
+	ularge.LowPart = file_time.dwLowDateTime;
+	ularge.HighPart = file_time.dwHighDateTime;
+
+	tp->tv_sec = (long) ((ularge.QuadPart - epoch) / 10000000L);
+	tp->tv_usec = (long) (system_time.wMilliseconds * 1000);
+
+	return 0;
+}
+
+#endif /* _MSC_VER */
diff -pruN 0.8.0-0.3/scrypt-windows-stubs/include/getopt.h 0.8.20-1/scrypt-windows-stubs/include/getopt.h
--- 0.8.0-0.3/scrypt-windows-stubs/include/getopt.h	1970-01-01 00:00:00.000000000 +0000
+++ 0.8.20-1/scrypt-windows-stubs/include/getopt.h	2022-02-21 10:55:27.000000000 +0000
@@ -0,0 +1,63 @@
+/*****************************************************************************
+* getopt.h - competent and free getopt library.
+* $Header: /cvsroot/freegetopt/freegetopt/getopt.h,v 1.2 2003/10/26 03:10:20 vindaci Exp $
+*
+* Copyright (c)2002-2003 Mark K. Kim
+* All rights reserved.
+* 
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*
+*   * Redistributions of source code must retain the above copyright
+*     notice, this list of conditions and the following disclaimer.
+*
+*   * Redistributions in binary form must reproduce the above copyright
+*     notice, this list of conditions and the following disclaimer in
+*     the documentation and/or other materials provided with the
+*     distribution.
+*
+*   * Neither the original author of this software nor the names of its
+*     contributors may be used to endorse or promote products derived
+*     from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+* DAMAGE.
+*/
+#ifndef GETOPT_H_
+#define GETOPT_H_
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+extern char* optarg;
+extern int optind;
+extern int opterr;
+extern int optopt;
+
+int getopt(int argc, char** argv, char* optstr);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* GETOPT_H_ */
+
+
+/* vim:ts=3
+*/
diff -pruN 0.8.0-0.3/scrypt-windows-stubs/include/inttypes.h 0.8.20-1/scrypt-windows-stubs/include/inttypes.h
--- 0.8.0-0.3/scrypt-windows-stubs/include/inttypes.h	1970-01-01 00:00:00.000000000 +0000
+++ 0.8.20-1/scrypt-windows-stubs/include/inttypes.h	2022-02-21 10:55:27.000000000 +0000
@@ -0,0 +1,305 @@
+// ISO C9x  compliant inttypes.h for Microsoft Visual Studio
+// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 
+// 
+//  Copyright (c) 2006 Alexander Chemeris
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+// 
+//   1. Redistributions of source code must retain the above copyright notice,
+//      this list of conditions and the following disclaimer.
+// 
+//   2. Redistributions in binary form must reproduce the above copyright
+//      notice, this list of conditions and the following disclaimer in the
+//      documentation and/or other materials provided with the distribution.
+// 
+//   3. The name of the author may be used to endorse or promote products
+//      derived from this software without specific prior written permission.
+// 
+// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// 
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef _MSC_VER // [
+#error "Use this header only with Microsoft Visual C++ compilers!"
+#endif // _MSC_VER ]
+
+#ifndef _MSC_INTTYPES_H_ // [
+#define _MSC_INTTYPES_H_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif
+
+#include "stdint.h"
+
+// 7.8 Format conversion of integer types
+
+typedef struct {
+   intmax_t quot;
+   intmax_t rem;
+} imaxdiv_t;
+
+// 7.8.1 Macros for format specifiers
+
+#if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS) // [   See footnote 185 at page 198
+
+// The fprintf macros for signed integers are:
+#define PRId8       "d"
+#define PRIi8       "i"
+#define PRIdLEAST8  "d"
+#define PRIiLEAST8  "i"
+#define PRIdFAST8   "d"
+#define PRIiFAST8   "i"
+
+#define PRId16       "hd"
+#define PRIi16       "hi"
+#define PRIdLEAST16  "hd"
+#define PRIiLEAST16  "hi"
+#define PRIdFAST16   "hd"
+#define PRIiFAST16   "hi"
+
+#define PRId32       "I32d"
+#define PRIi32       "I32i"
+#define PRIdLEAST32  "I32d"
+#define PRIiLEAST32  "I32i"
+#define PRIdFAST32   "I32d"
+#define PRIiFAST32   "I32i"
+
+#define PRId64       "I64d"
+#define PRIi64       "I64i"
+#define PRIdLEAST64  "I64d"
+#define PRIiLEAST64  "I64i"
+#define PRIdFAST64   "I64d"
+#define PRIiFAST64   "I64i"
+
+#define PRIdMAX     "I64d"
+#define PRIiMAX     "I64i"
+
+#define PRIdPTR     "Id"
+#define PRIiPTR     "Ii"
+
+// The fprintf macros for unsigned integers are:
+#define PRIo8       "o"
+#define PRIu8       "u"
+#define PRIx8       "x"
+#define PRIX8       "X"
+#define PRIoLEAST8  "o"
+#define PRIuLEAST8  "u"
+#define PRIxLEAST8  "x"
+#define PRIXLEAST8  "X"
+#define PRIoFAST8   "o"
+#define PRIuFAST8   "u"
+#define PRIxFAST8   "x"
+#define PRIXFAST8   "X"
+
+#define PRIo16       "ho"
+#define PRIu16       "hu"
+#define PRIx16       "hx"
+#define PRIX16       "hX"
+#define PRIoLEAST16  "ho"
+#define PRIuLEAST16  "hu"
+#define PRIxLEAST16  "hx"
+#define PRIXLEAST16  "hX"
+#define PRIoFAST16   "ho"
+#define PRIuFAST16   "hu"
+#define PRIxFAST16   "hx"
+#define PRIXFAST16   "hX"
+
+#define PRIo32       "I32o"
+#define PRIu32       "I32u"
+#define PRIx32       "I32x"
+#define PRIX32       "I32X"
+#define PRIoLEAST32  "I32o"
+#define PRIuLEAST32  "I32u"
+#define PRIxLEAST32  "I32x"
+#define PRIXLEAST32  "I32X"
+#define PRIoFAST32   "I32o"
+#define PRIuFAST32   "I32u"
+#define PRIxFAST32   "I32x"
+#define PRIXFAST32   "I32X"
+
+#define PRIo64       "I64o"
+#define PRIu64       "I64u"
+#define PRIx64       "I64x"
+#define PRIX64       "I64X"
+#define PRIoLEAST64  "I64o"
+#define PRIuLEAST64  "I64u"
+#define PRIxLEAST64  "I64x"
+#define PRIXLEAST64  "I64X"
+#define PRIoFAST64   "I64o"
+#define PRIuFAST64   "I64u"
+#define PRIxFAST64   "I64x"
+#define PRIXFAST64   "I64X"
+
+#define PRIoMAX     "I64o"
+#define PRIuMAX     "I64u"
+#define PRIxMAX     "I64x"
+#define PRIXMAX     "I64X"
+
+#define PRIoPTR     "Io"
+#define PRIuPTR     "Iu"
+#define PRIxPTR     "Ix"
+#define PRIXPTR     "IX"
+
+// The fscanf macros for signed integers are:
+#define SCNd8       "d"
+#define SCNi8       "i"
+#define SCNdLEAST8  "d"
+#define SCNiLEAST8  "i"
+#define SCNdFAST8   "d"
+#define SCNiFAST8   "i"
+
+#define SCNd16       "hd"
+#define SCNi16       "hi"
+#define SCNdLEAST16  "hd"
+#define SCNiLEAST16  "hi"
+#define SCNdFAST16   "hd"
+#define SCNiFAST16   "hi"
+
+#define SCNd32       "ld"
+#define SCNi32       "li"
+#define SCNdLEAST32  "ld"
+#define SCNiLEAST32  "li"
+#define SCNdFAST32   "ld"
+#define SCNiFAST32   "li"
+
+#define SCNd64       "I64d"
+#define SCNi64       "I64i"
+#define SCNdLEAST64  "I64d"
+#define SCNiLEAST64  "I64i"
+#define SCNdFAST64   "I64d"
+#define SCNiFAST64   "I64i"
+
+#define SCNdMAX     "I64d"
+#define SCNiMAX     "I64i"
+
+#ifdef _WIN64 // [
+#  define SCNdPTR     "I64d"
+#  define SCNiPTR     "I64i"
+#else  // _WIN64 ][
+#  define SCNdPTR     "ld"
+#  define SCNiPTR     "li"
+#endif  // _WIN64 ]
+
+// The fscanf macros for unsigned integers are:
+#define SCNo8       "o"
+#define SCNu8       "u"
+#define SCNx8       "x"
+#define SCNX8       "X"
+#define SCNoLEAST8  "o"
+#define SCNuLEAST8  "u"
+#define SCNxLEAST8  "x"
+#define SCNXLEAST8  "X"
+#define SCNoFAST8   "o"
+#define SCNuFAST8   "u"
+#define SCNxFAST8   "x"
+#define SCNXFAST8   "X"
+
+#define SCNo16       "ho"
+#define SCNu16       "hu"
+#define SCNx16       "hx"
+#define SCNX16       "hX"
+#define SCNoLEAST16  "ho"
+#define SCNuLEAST16  "hu"
+#define SCNxLEAST16  "hx"
+#define SCNXLEAST16  "hX"
+#define SCNoFAST16   "ho"
+#define SCNuFAST16   "hu"
+#define SCNxFAST16   "hx"
+#define SCNXFAST16   "hX"
+
+#define SCNo32       "lo"
+#define SCNu32       "lu"
+#define SCNx32       "lx"
+#define SCNX32       "lX"
+#define SCNoLEAST32  "lo"
+#define SCNuLEAST32  "lu"
+#define SCNxLEAST32  "lx"
+#define SCNXLEAST32  "lX"
+#define SCNoFAST32   "lo"
+#define SCNuFAST32   "lu"
+#define SCNxFAST32   "lx"
+#define SCNXFAST32   "lX"
+
+#define SCNo64       "I64o"
+#define SCNu64       "I64u"
+#define SCNx64       "I64x"
+#define SCNX64       "I64X"
+#define SCNoLEAST64  "I64o"
+#define SCNuLEAST64  "I64u"
+#define SCNxLEAST64  "I64x"
+#define SCNXLEAST64  "I64X"
+#define SCNoFAST64   "I64o"
+#define SCNuFAST64   "I64u"
+#define SCNxFAST64   "I64x"
+#define SCNXFAST64   "I64X"
+
+#define SCNoMAX     "I64o"
+#define SCNuMAX     "I64u"
+#define SCNxMAX     "I64x"
+#define SCNXMAX     "I64X"
+
+#ifdef _WIN64 // [
+#  define SCNoPTR     "I64o"
+#  define SCNuPTR     "I64u"
+#  define SCNxPTR     "I64x"
+#  define SCNXPTR     "I64X"
+#else  // _WIN64 ][
+#  define SCNoPTR     "lo"
+#  define SCNuPTR     "lu"
+#  define SCNxPTR     "lx"
+#  define SCNXPTR     "lX"
+#endif  // _WIN64 ]
+
+#endif // __STDC_FORMAT_MACROS ]
+
+// 7.8.2 Functions for greatest-width integer types
+
+// 7.8.2.1 The imaxabs function
+#define imaxabs _abs64
+
+// 7.8.2.2 The imaxdiv function
+
+// This is modified version of div() function from Microsoft's div.c found
+// in %MSVC.NET%\crt\src\div.c
+#ifdef STATIC_IMAXDIV // [
+static
+#else // STATIC_IMAXDIV ][
+_inline
+#endif // STATIC_IMAXDIV ]
+imaxdiv_t __cdecl imaxdiv(intmax_t numer, intmax_t denom)
+{
+   imaxdiv_t result;
+
+   result.quot = numer / denom;
+   result.rem = numer % denom;
+
+   if (numer < 0 && result.rem > 0) {
+      // did division wrong; must fix up
+      ++result.quot;
+      result.rem -= denom;
+   }
+
+   return result;
+}
+
+// 7.8.2.3 The strtoimax and strtoumax functions
+#define strtoimax _strtoi64
+#define strtoumax _strtoui64
+
+// 7.8.2.4 The wcstoimax and wcstoumax functions
+#define wcstoimax _wcstoi64
+#define wcstoumax _wcstoui64
+
+
+#endif // _MSC_INTTYPES_H_ ]
diff -pruN 0.8.0-0.3/scrypt-windows-stubs/include/stdint.h 0.8.20-1/scrypt-windows-stubs/include/stdint.h
--- 0.8.0-0.3/scrypt-windows-stubs/include/stdint.h	1970-01-01 00:00:00.000000000 +0000
+++ 0.8.20-1/scrypt-windows-stubs/include/stdint.h	2022-02-21 10:55:27.000000000 +0000
@@ -0,0 +1,255 @@
+// ISO C9x  compliant stdint.h for Microsoft Visual Studio
+// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124
+//
+//  Copyright (c) 2006-2008 Alexander Chemeris
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+//   1. Redistributions of source code must retain the above copyright notice,
+//      this list of conditions and the following disclaimer.
+//
+//   2. Redistributions in binary form must reproduce the above copyright
+//      notice, this list of conditions and the following disclaimer in the
+//      documentation and/or other materials provided with the distribution.
+//
+//   3. The name of the author may be used to endorse or promote products
+//      derived from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef _MSC_VER // [
+#error "Use this header only with Microsoft Visual C++ compilers!"
+#endif // _MSC_VER ]
+
+#ifndef _MSC_STDINT_H_ // [
+#define _MSC_STDINT_H_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif
+
+#include <limits.h>
+
+// For Visual Studio 6 in C++ mode and for many Visual Studio versions when
+// compiling for ARM we should wrap <wchar.h> include with 'extern "C++" {}'
+// or compiler give many errors like this:
+//   error C2733: second C linkage of overloaded function 'wmemchr' not allowed
+#ifdef __cplusplus
+extern "C" {
+#endif
+#  include <wchar.h>
+#ifdef __cplusplus
+}
+#endif
+
+// Define _W64 macros to mark types changing their size, like intptr_t.
+#ifndef _W64
+#  if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300
+#     define _W64 __w64
+#  else
+#     define _W64
+#  endif
+#endif
+
+
+// 7.18.1 Integer types
+
+// 7.18.1.1 Exact-width integer types
+
+// Visual Studio 6 and Embedded Visual C++ 4 doesn't
+// realize that, e.g. char has the same size as __int8
+// so we give up on __intX for them.
+#if (_MSC_VER < 1300)
+   typedef signed char       int8_t;
+   typedef signed short      int16_t;
+   typedef signed int        int32_t;
+   typedef unsigned char     uint8_t;
+   typedef unsigned short    uint16_t;
+   typedef unsigned int      uint32_t;
+#else
+   typedef signed __int8     int8_t;
+   typedef signed __int16    int16_t;
+   typedef signed __int32    int32_t;
+   typedef unsigned __int8   uint8_t;
+   typedef unsigned __int16  uint16_t;
+   typedef unsigned __int32  uint32_t;
+#endif
+typedef signed __int64       int64_t;
+typedef unsigned __int64     uint64_t;
+
+
+// 7.18.1.2 Minimum-width integer types
+typedef int8_t    int_least8_t;
+typedef int16_t   int_least16_t;
+typedef int32_t   int_least32_t;
+typedef int64_t   int_least64_t;
+typedef uint8_t   uint_least8_t;
+typedef uint16_t  uint_least16_t;
+typedef uint32_t  uint_least32_t;
+typedef uint64_t  uint_least64_t;
+
+// 7.18.1.3 Fastest minimum-width integer types
+typedef int8_t    int_fast8_t;
+typedef int16_t   int_fast16_t;
+typedef int32_t   int_fast32_t;
+typedef int64_t   int_fast64_t;
+typedef uint8_t   uint_fast8_t;
+typedef uint16_t  uint_fast16_t;
+typedef uint32_t  uint_fast32_t;
+typedef uint64_t  uint_fast64_t;
+
+// 7.18.1.4 Integer types capable of holding object pointers
+#ifdef _WIN64 // [
+   typedef signed __int64    intptr_t;
+   typedef unsigned __int64  uintptr_t;
+#else // _WIN64 ][
+   typedef _W64 signed int   intptr_t;
+   typedef _W64 unsigned int uintptr_t;
+#endif // _WIN64 ]
+
+// 7.18.1.5 Greatest-width integer types
+typedef int64_t   intmax_t;
+typedef uint64_t  uintmax_t;
+
+
+// 7.18.2 Limits of specified-width integer types
+
+#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [   See footnote 220 at page 257 and footnote 221 at page 259
+
+// 7.18.2.1 Limits of exact-width integer types
+#define INT8_MIN     ((int8_t)_I8_MIN)
+#define INT8_MAX     _I8_MAX
+#define INT16_MIN    ((int16_t)_I16_MIN)
+#define INT16_MAX    _I16_MAX
+#define INT32_MIN    ((int32_t)_I32_MIN)
+#define INT32_MAX    _I32_MAX
+#define INT64_MIN    ((int64_t)_I64_MIN)
+#define INT64_MAX    _I64_MAX
+#define UINT8_MAX    _UI8_MAX
+#define UINT16_MAX   _UI16_MAX
+#define UINT32_MAX   _UI32_MAX
+#define UINT64_MAX   _UI64_MAX
+
+// 7.18.2.2 Limits of minimum-width integer types
+#define INT_LEAST8_MIN    INT8_MIN
+#define INT_LEAST8_MAX    INT8_MAX
+#define INT_LEAST16_MIN   INT16_MIN
+#define INT_LEAST16_MAX   INT16_MAX
+#define INT_LEAST32_MIN   INT32_MIN
+#define INT_LEAST32_MAX   INT32_MAX
+#define INT_LEAST64_MIN   INT64_MIN
+#define INT_LEAST64_MAX   INT64_MAX
+#define UINT_LEAST8_MAX   UINT8_MAX
+#define UINT_LEAST16_MAX  UINT16_MAX
+#define UINT_LEAST32_MAX  UINT32_MAX
+#define UINT_LEAST64_MAX  UINT64_MAX
+
+// 7.18.2.3 Limits of fastest minimum-width integer types
+#define INT_FAST8_MIN    INT8_MIN
+#define INT_FAST8_MAX    INT8_MAX
+#define INT_FAST16_MIN   INT16_MIN
+#define INT_FAST16_MAX   INT16_MAX
+#define INT_FAST32_MIN   INT32_MIN
+#define INT_FAST32_MAX   INT32_MAX
+#define INT_FAST64_MIN   INT64_MIN
+#define INT_FAST64_MAX   INT64_MAX
+#define UINT_FAST8_MAX   UINT8_MAX
+#define UINT_FAST16_MAX  UINT16_MAX
+#define UINT_FAST32_MAX  UINT32_MAX
+#define UINT_FAST64_MAX  UINT64_MAX
+
+// 7.18.2.4 Limits of integer types capable of holding object pointers
+#ifdef _WIN64 // [
+#  define INTPTR_MIN   INT64_MIN
+#  define INTPTR_MAX   INT64_MAX
+#  define UINTPTR_MAX  UINT64_MAX
+#else // _WIN64 ][
+#  define INTPTR_MIN   INT32_MIN
+#  define INTPTR_MAX   INT32_MAX
+#  define UINTPTR_MAX  UINT32_MAX
+#endif // _WIN64 ]
+
+// 7.18.2.5 Limits of greatest-width integer types
+#define INTMAX_MIN   INT64_MIN
+#define INTMAX_MAX   INT64_MAX
+#define UINTMAX_MAX  UINT64_MAX
+
+// 7.18.3 Limits of other integer types
+
+#ifdef _WIN64 // [
+#  define PTRDIFF_MIN  _I64_MIN
+#  define PTRDIFF_MAX  _I64_MAX
+#else  // _WIN64 ][
+#  define PTRDIFF_MIN  _I32_MIN
+#  define PTRDIFF_MAX  _I32_MAX
+#endif  // _WIN64 ]
+
+#define SIG_ATOMIC_MIN  INT_MIN
+#define SIG_ATOMIC_MAX  INT_MAX
+
+#ifndef SIZE_MAX // [
+#  ifdef _WIN64 // [
+#     define SIZE_MAX  _UI64_MAX
+#  else // _WIN64 ][
+#     define SIZE_MAX  _UI32_MAX
+#  endif // _WIN64 ]
+#endif // SIZE_MAX ]
+
+#ifndef SSIZE_MAX // [
+#  ifdef _WIN64 // [
+#     define SSIZE_MAX _I64_MAX
+#  else // _WIN64 ][
+#     define SSIZE_MAX _I32_MAX
+#  endif // _WIN64 ]
+#endif // SIZE_MAX ]
+
+// WCHAR_MIN and WCHAR_MAX are also defined in <wchar.h>
+#ifndef WCHAR_MIN // [
+#  define WCHAR_MIN  0
+#endif  // WCHAR_MIN ]
+#ifndef WCHAR_MAX // [
+#  define WCHAR_MAX  _UI16_MAX
+#endif  // WCHAR_MAX ]
+
+#define WINT_MIN  0
+#define WINT_MAX  _UI16_MAX
+
+#endif // __STDC_LIMIT_MACROS ]
+
+
+// 7.18.4 Limits of other integer types
+
+#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [   See footnote 224 at page 260
+
+// 7.18.4.1 Macros for minimum-width integer constants
+
+#define INT8_C(val)  val##i8
+#define INT16_C(val) val##i16
+#define INT32_C(val) val##i32
+#define INT64_C(val) val##i64
+
+#define UINT8_C(val)  val##ui8
+#define UINT16_C(val) val##ui16
+#define UINT32_C(val) val##ui32
+#define UINT64_C(val) val##ui64
+
+// 7.18.4.2 Macros for greatest-width integer constants
+#define INTMAX_C   INT64_C
+#define UINTMAX_C  UINT64_C
+
+#endif // __STDC_CONSTANT_MACROS ]
+
+
+#endif // _MSC_STDINT_H_ ]
diff -pruN 0.8.0-0.3/scrypt-windows-stubs/include/sys/time.h 0.8.20-1/scrypt-windows-stubs/include/sys/time.h
--- 0.8.0-0.3/scrypt-windows-stubs/include/sys/time.h	1970-01-01 00:00:00.000000000 +0000
+++ 0.8.20-1/scrypt-windows-stubs/include/sys/time.h	2022-02-21 10:55:27.000000000 +0000
@@ -0,0 +1,19 @@
+#ifndef _MY_GETTIMEOFDAY_H_
+#define _MY_GETTIMEOFDAY_H_
+
+#ifdef _MSC_VER
+
+#include <time.h>
+#include <winsock2.h>
+int gettimeofday(struct timeval * tp, struct timezone * tzp);
+
+#if _MSC_VER < 1900
+struct timespec {
+       time_t tv_sec;
+       long tv_nsec;
+};
+#endif
+
+#endif /* _MSC_VER */
+
+#endif /* _MY_GETTIMEOFDAY_H_ */
diff -pruN 0.8.0-0.3/scrypt-windows-stubs/include/unistd.h 0.8.20-1/scrypt-windows-stubs/include/unistd.h
--- 0.8.0-0.3/scrypt-windows-stubs/include/unistd.h	1970-01-01 00:00:00.000000000 +0000
+++ 0.8.20-1/scrypt-windows-stubs/include/unistd.h	2022-02-21 10:55:27.000000000 +0000
@@ -0,0 +1,48 @@
+/*
+ * Copied from StackOverflow:
+ *  http://stackoverflow.com/a/826027
+ */
+
+#ifndef _UNISTD_H
+#define _UNISTD_H    1
+
+/* This file intended to serve as a drop-in replacement for 
+ *  unistd.h on Windows
+ *  Please add functionality as neeeded 
+ */
+
+#include <stdlib.h>
+#include <io.h>
+#include <getopt.h> /* getopt at: https://gist.github.com/ashelly/7776712*/
+#include <process.h> /* for getpid() and the exec..() family */
+
+#define srandom srand
+#define random rand
+
+/* Values for the second argument to access.
+   These may be OR'd together.  */
+#define R_OK    4       /* Test for read permission.  */
+#define W_OK    2       /* Test for write permission.  */
+//#define   X_OK    1       /* execute permission - unsupported in windows*/
+#define F_OK    0       /* Test for existence.  */
+
+#define access _access
+#define ftruncate _chsize
+#define unlink _unlink
+
+#define ssize_t int
+
+#define STDIN_FILENO 0
+#define STDOUT_FILENO 1
+#define STDERR_FILENO 2
+/* should be in some equivalent to <sys/types.h> */
+typedef __int8            int8_t;
+typedef __int16           int16_t; 
+typedef __int32           int32_t;
+typedef __int64           int64_t;
+typedef unsigned __int8   uint8_t;
+typedef unsigned __int16  uint16_t;
+typedef unsigned __int32  uint32_t;
+typedef unsigned __int64  uint64_t;
+
+#endif /* unistd.h  */
diff -pruN 0.8.0-0.3/setup.cfg 0.8.20-1/setup.cfg
--- 0.8.0-0.3/setup.cfg	2016-09-17 13:30:16.000000000 +0000
+++ 0.8.20-1/setup.cfg	1970-01-01 00:00:00.000000000 +0000
@@ -1,5 +0,0 @@
-[egg_info]
-tag_build = 
-tag_date = 0
-tag_svn_revision = 0
-
diff -pruN 0.8.0-0.3/setup.py 0.8.20-1/setup.py
--- 0.8.0-0.3/setup.py	2016-09-17 13:28:50.000000000 +0000
+++ 0.8.20-1/setup.py	2022-02-21 10:55:27.000000000 +0000
@@ -1,11 +1,14 @@
 #!/usr/bin/env python
+# -*- coding: utf-8 -*-
 from setuptools import setup, Extension
 
 import sys
 import platform
 import struct
+import os
 
 includes = []
+libraries = []
 library_dirs = []
 extra_sources = []
 CFLAGS = []
@@ -22,21 +25,47 @@ if sys.platform.startswith('linux'):
                      ('HAVE_SYS_SYSINFO_H', '1'),
                      ('_FILE_OFFSET_BITS', '64')]
     libraries = ['crypto', 'rt']
+    includes = ['/usr/local/include', '/usr/include']
     CFLAGS.append('-O2')
 elif sys.platform.startswith('win32'):
     define_macros = [('inline', '__inline')]
-    libraries = ['libeay32', 'advapi32']
-    extra_sources = ['scrypt-windows-stubs/gettimeofday.c']
 
+    extra_sources = ['scrypt-windows-stubs/gettimeofday.c']
     if struct.calcsize('P') == 8:
-        library_dirs = ['c:\OpenSSL-Win64\lib']
-        includes = ['c:\OpenSSL-Win64\include', 'scrypt-windows-stubs/include']
+        if os.path.isdir('c:\OpenSSL-v111-Win64') and sys.version_info[0] >= 3 and sys.version_info[1] > 4:
+            openssl_dir = 'c:\OpenSSL-v111-Win64'
+        elif os.path.isdir('c:\Program Files\OpenSSL-Win64'):
+            openssl_dir = 'c:\Program Files\OpenSSL-Win64'
+        else:
+            openssl_dir = 'c:\OpenSSL-Win64'
+        library_dirs = [openssl_dir + '\lib']
+        includes = [openssl_dir + '\include', 'scrypt-windows-stubs/include']
+    else:
+        if os.path.isdir('c:\OpenSSL-v111-Win32'):
+            openssl_dir = 'c:\OpenSSL-v111-Win32'
+        elif os.path.isdir('c:\Program Files (x86)\OpenSSL-Win32'):
+            openssl_dir = 'c:\Program Files (x86)\OpenSSL-Win32'
+        else:
+            openssl_dir = 'c:\OpenSSL-Win32'
+        library_dirs = [openssl_dir + '\lib']
+        includes = [openssl_dir + '\include', 'scrypt-windows-stubs/include']
+    windows_link_legacy_openssl = os.environ.get(
+        "SCRYPT_WINDOWS_LINK_LEGACY_OPENSSL", None
+    )
+    if  windows_link_legacy_openssl is None:
+        libraries = ['libcrypto_static']
     else:
-        library_dirs = ['c:\OpenSSL-Win32\lib']
-        includes = ['c:\OpenSSL-Win32\include', 'scrypt-windows-stubs/include']
+        libraries = ['libeay32']
+    libraries += ["advapi32", "gdi32", "user32", "ws2_32"]
 
 elif sys.platform.startswith('darwin') and platform.mac_ver()[0] < '10.6':
     define_macros = [('HAVE_SYSCTL_HW_USERMEM', '1')]
+        # disable for travis
+    libraries = ['crypto']
+elif sys.platform.startswith('darwin'):
+    define_macros = [('HAVE_POSIX_MEMALIGN', '1'),
+                     ('HAVE_SYSCTL_HW_USERMEM', '1')]
+        # disable for travis
     libraries = ['crypto']
 else:
     define_macros = [('HAVE_POSIX_MEMALIGN', '1'),
@@ -46,51 +75,57 @@ else:
 scrypt_module = Extension(
     '_scrypt',
     sources=['src/scrypt.c',
-             'scrypt-1.2.0/lib/crypto/crypto_scrypt_smix_sse2.c',
-             'scrypt-1.2.0/lib/crypto/crypto_scrypt_smix.c',
-             'scrypt-1.2.0/lib/crypto/crypto_scrypt.c',
-             'scrypt-1.2.0/lib/scryptenc/scryptenc.c',
-             'scrypt-1.2.0/lib/scryptenc/scryptenc_cpuperf.c',
-             'scrypt-1.2.0/lib/util/memlimit.c',
-             'scrypt-1.2.0/libcperciva/alg/sha256.c',
-             'scrypt-1.2.0/libcperciva/crypto/crypto_aes_aesni.c',
-             'scrypt-1.2.0/libcperciva/crypto/crypto_aes.c',
-             'scrypt-1.2.0/libcperciva/crypto/crypto_aesctr.c',
-             'scrypt-1.2.0/libcperciva/crypto/crypto_entropy.c',
-             'scrypt-1.2.0/libcperciva/util/entropy.c',
-             'scrypt-1.2.0/libcperciva/util/insecure_memzero.c',
-             'scrypt-1.2.0/libcperciva/util/warnp.c'] + extra_sources,
-    include_dirs=['scrypt-1.2.0',
-                  'scrypt-1.2.0/lib',
-                  'scrypt-1.2.0/lib/scryptenc',
-                  'scrypt-1.2.0/lib/crypto',
-                  'scrypt-1.2.0/lib/util',
-                  'scrypt-1.2.0/libcperciva/cpusupport',
-                  'scrypt-1.2.0/libcperciva/alg',
-                  'scrypt-1.2.0/libcperciva/util',
-                  'scrypt-1.2.0/libcperciva/crypto'] + includes,
+             'scrypt-1.2.1/lib/crypto/crypto_scrypt_smix_sse2.c',
+             'scrypt-1.2.1/lib/crypto/crypto_scrypt_smix.c',
+             'scrypt-1.2.1/lib/crypto/crypto_scrypt.c',
+             'scrypt-1.2.1/lib/scryptenc/scryptenc.c',
+             'scrypt-1.2.1/lib/scryptenc/scryptenc_cpuperf.c',
+             'scrypt-1.2.1/lib/util/memlimit.c',
+             'scrypt-1.2.1/libcperciva/alg/sha256.c',
+             'scrypt-1.2.1/libcperciva/crypto/crypto_aes_aesni.c',
+             'scrypt-1.2.1/libcperciva/crypto/crypto_aes.c',
+             'scrypt-1.2.1/libcperciva/crypto/crypto_aesctr.c',
+             'scrypt-1.2.1/libcperciva/crypto/crypto_entropy.c',
+             'scrypt-1.2.1/libcperciva/util/entropy.c',
+             'scrypt-1.2.1/libcperciva/util/insecure_memzero.c',
+             'scrypt-1.2.1/libcperciva/util/warnp.c',
+             'scrypt-1.2.1/libcperciva/util/humansize.c',
+             'scrypt-1.2.1/libcperciva/util/asprintf.c'] + extra_sources,
+    include_dirs=['scrypt-1.2.1',
+                  'scrypt-1.2.1/lib',
+                  'scrypt-1.2.1/lib/scryptenc',
+                  'scrypt-1.2.1/lib/crypto',
+                  'scrypt-1.2.1/lib/util',
+                  'scrypt-1.2.1/libcperciva/cpusupport',
+                  'scrypt-1.2.1/libcperciva/alg',
+                  'scrypt-1.2.1/libcperciva/util',
+                  'scrypt-1.2.1/libcperciva/crypto'] + includes,
     define_macros=[('HAVE_CONFIG_H', None)] + define_macros,
     extra_compile_args=CFLAGS,
     library_dirs=library_dirs,
     libraries=libraries)
 
 setup(name='scrypt',
-      version='0.8.0',
+      version='0.8.20',
       description='Bindings for the scrypt key derivation function library',
       author='Magnus Hallin',
       author_email='mhallin@gmail.com',
-      url='http://bitbucket.org/mhallin/py-scrypt',
-      py_modules=['scrypt'],
+      maintainer="Holger Nahrstaedt",
+      maintainer_email="nahrstaedt@gmail.com",
+      url='https://github.com/holgern/py-scrypt',
+      packages=['scrypt', 'scrypt.tests'],
+      package_data={'scrypt': ['tests/*.csv']},
       ext_modules=[scrypt_module],
       classifiers=['Development Status :: 4 - Beta',
                    'Intended Audience :: Developers',
                    'License :: OSI Approved :: BSD License',
                    'Programming Language :: Python :: 2.7',
                    'Programming Language :: Python :: 3',
-                   'Programming Language :: Python :: 3.4',
-                   'Programming Language :: Python :: 3.5',
+                   'Programming Language :: Python :: 3.6',
+                   'Programming Language :: Python :: 3.7',
+                   'Programming Language :: Python :: 3.8',
+                   'Programming Language :: Python :: 3.9',
                    'Topic :: Security :: Cryptography',
                    'Topic :: Software Development :: Libraries'],
       license='2-clause BSD',
-      long_description=open('README.rst').read(),
-      test_suite='tests.all_tests')
+      long_description=open('README.rst').read())
diff -pruN 0.8.0-0.3/src/scrypt.c 0.8.20-1/src/scrypt.c
--- 0.8.0-0.3/src/scrypt.c	2015-07-05 11:37:52.000000000 +0000
+++ 0.8.20-1/src/scrypt.c	2022-02-21 10:55:27.000000000 +0000
@@ -1,5 +1,6 @@
 /*-
  * Copyright 2010 Magnus Hallin
+ *           2018 Holger Nahrstaedt
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -44,17 +45,17 @@
 DL_EXPORT(int) exp_scryptenc_buf(const uint8_t *inbuf, size_t inbuflen,
                                  uint8_t *outbuf,
                                  const uint8_t *passwd, size_t passwdlen,
-                                 size_t maxmem, double maxmemfrac, double maxtime) {
+                                 size_t maxmem, double maxmemfrac, double maxtime, int verbose) {
     return scryptenc_buf(inbuf, inbuflen, outbuf, passwd, passwdlen,
-                         maxmem, maxmemfrac, maxtime);
+                         maxmem, maxmemfrac, maxtime, verbose);
 }
 
 DL_EXPORT(int) exp_scryptdec_buf(const uint8_t *inbuf, size_t inbuflen,
                                  uint8_t *outbuf, size_t *outbuflen,
                                  const uint8_t *passwd, size_t passwdlen,
-                                 size_t maxmem, double maxmemfrac, double maxtime) {
+                                 size_t maxmem, double maxmemfrac, double maxtime, int verbose, int force) {
     return scryptdec_buf(inbuf, inbuflen, outbuf, outbuflen, passwd, passwdlen,
-                         maxmem, maxmemfrac, maxtime);
+                         maxmem, maxmemfrac, maxtime, verbose, force);
 }
 
 DL_EXPORT(int) exp_crypto_scrypt(const uint8_t *passwd, size_t passwdlen,
diff -pruN 0.8.0-0.3/tests/ciphertexts.csv 0.8.20-1/tests/ciphertexts.csv
--- 0.8.0-0.3/tests/ciphertexts.csv	2015-07-05 10:02:58.000000000 +0000
+++ 0.8.20-1/tests/ciphertexts.csv	1970-01-01 00:00:00.000000000 +0000
@@ -1,6 +0,0 @@
-input,password,maxtime,maxmem,maxmemfrac,ciphertext
-message,password,0.01,0,0.0625,736372797074000a00000008000000019f6d3fe5e9423a12d330e35089befdfbb476c7d4faea91492a2561f942c1599701aba424220218b9f81812df06d7cf2a281fd0fdbc7c9d978c335bf5209b1062ee2e49993c4d3a37d347ad6bf0eaecc2fe579a6f320b0acf475882c222c0ba34a7ac5379bedc82358bb3f736ea31d4b824e8bc95c75579
-message,password,5.0000,0.0000,0.1250,736372797074000a00000008000000cb974d55992fea307caa3593205c8851cd56b3ddfd241ee7b1c075cfd2e2f871dddcee71b6bc2b6b075caa1699ea58ce32e9fcd802b18069828201692380574e23e84c2d39d6a951c9c2401dea1a0fa44195b01fca9332f7aac223c84251c69a28037788e09cf297a003a62e2e7c5b6f039e3c1d21fa5da6
-message,password,0.5000,0.0000,0.0625,736372797074000a00000008000000141429bb22aef840e1dde29564dada8f2a77fc2855fe8c9e27e5bf5df4a0eec330344e8471bf83e2466a28acc9d1813a3e50e64697fb8e9c7c17954950f16a5b78fe114d8b147c5936802fe52b17f83e6da9de884257f2a938aa37c2e92b1c33cd9afd0f5e91baba29be4b1c0709bd2a31a4c52394f9b0d4
-message,password,0.5000,0.0000,0.1250,736372797074000a0000000800000014e9baa49b57b2e5b561df54121d870532714f063f295c15ca48e32b677e8e11126ab8da24683951749a19eede36ea3768cb01e8eda6c0f570db7051e07e99d2d687ce28f96aa2e6afa8a0a8c5d902c847e041e14435a22d873c4e676f7a7f5ab9107171b583d02724c056707640931a3c160b9e0ef87bae
-message,password,0.5000,10485760.0000,0.1250,736372797074000a0000000800000014e53c55cd89b6e2de639c1621d92e79212e5f4fc793387435486427eb8adeb192382b5b6397f98ac66fa528a13cba01bd611082369fe1e2244a01ba8329ff6fcaa2db5e87fb75683ae6fc636d873c2e004a0209b947c7b8e805174d65ec0ac2cb597baadae6cf092c33a5096590860b51570faa89e39bf0
\ No newline at end of file
diff -pruN 0.8.0-0.3/tests/hashvectors.csv 0.8.20-1/tests/hashvectors.csv
--- 0.8.0-0.3/tests/hashvectors.csv	2015-02-08 19:29:00.000000000 +0000
+++ 0.8.20-1/tests/hashvectors.csv	1970-01-01 00:00:00.000000000 +0000
@@ -1,5 +0,0 @@
-password,salt,n,r,p,hexhash
-,,16,1,1,77d6576238657b203b19ca42c18a0497f16b4844e3074ae8dfdffa3fede21442fcd0069ded0948f8326a753a0fc81f17e8d3e0fb2e0d3628cf35e20c38d18906
-password,NaCl,1024,8,16,fdbabe1c9d3472007856e7190d01e9fe7c6ad7cbc8237830e77376634b3731622eaf30d92e22a3886ff109279d9830dac727afb94a83ee6d8360cbdfa2cc0640
-pleaseletmein,SodiumChloride,16384,8,1,7023bdcb3afd7348461c06cd81fd38ebfda8fbba904f8e3ea9b543f6545da1f2d5432955613f0fcf62d49705242a9af9e61e85dc0d651e40dfcf017b45575887
-pleaseletmein,SodiumChloride,32768,16,4,cbc397a9b5f5a53048c5b9f039ee1246d9532c8089fb346a4ab47cd0701febf18652b1ee042e070d1b6c631c43fd05ececd5b165ee1c2ffc1a2e98406fc2cd52
\ No newline at end of file
diff -pruN 0.8.0-0.3/tests/__init__.py 0.8.20-1/tests/__init__.py
--- 0.8.0-0.3/tests/__init__.py	2015-07-05 11:29:05.000000000 +0000
+++ 0.8.20-1/tests/__init__.py	1970-01-01 00:00:00.000000000 +0000
@@ -1,36 +0,0 @@
-from sys import version_info, exit
-
-from .test_scrypt import TestScrypt, TestScryptHash
-from .test_scrypt_c_module import TestScryptCModule
-from .test_scrypt_py2x import TestScryptForPython2
-from .test_scrypt_py3x import TestScryptForPy3
-
-if ((version_info > (3, 2, 0, 'final', 0)) or
-        (version_info > (2, 7, 0, 'final', 0) and
-         version_info < (3, 0, 0, 'final', 0))):
-    import unittest as testm
-else:
-    try:
-        import unittest2 as testm
-    except ImportError:
-        print("Please install unittest2 to run the test suite")
-        exit(-1)
-
-
-def all_tests():
-    suite = testm.TestSuite()
-    loader = testm.TestLoader()
-
-    test_classes = [
-        TestScrypt,
-        TestScryptCModule,
-        TestScryptHash,
-        TestScryptForPython2,
-        TestScryptForPy3,
-    ]
-
-    for cls in test_classes:
-        tests = loader.loadTestsFromTestCase(cls)
-        suite.addTests(tests)
-
-    return suite
diff -pruN 0.8.0-0.3/tests/test_scrypt.py 0.8.20-1/tests/test_scrypt.py
--- 0.8.0-0.3/tests/test_scrypt.py	2015-07-05 16:51:29.000000000 +0000
+++ 0.8.20-1/tests/test_scrypt.py	1970-01-01 00:00:00.000000000 +0000
@@ -1,284 +0,0 @@
-# -*- coding: utf-8 -*-
-
-from os import urandom
-from os.path import dirname, abspath, sep
-from sys import version_info, exit
-from csv import reader
-from binascii import a2b_hex, b2a_hex
-
-import scrypt
-
-if ((version_info > (3, 2, 0, 'final', 0)) or
-        (version_info > (2, 7, 0, 'final', 0) and
-         version_info < (3, 0, 0, 'final', 0))):
-    import unittest as testm
-else:
-    try:
-        import unittest2 as testm
-    except ImportError:
-        print("Please install unittest2 to run the test suite")
-        exit(-1)
-
-
-class TestScrypt(testm.TestCase):
-
-    def setUp(self):
-        self.input = "message"
-        self.password = "password"
-        self.longinput = str(urandom(100000))
-        self.five_minutes = 300.0
-        self.five_seconds = 5.0
-        self.one_byte = 1  # in Bytes
-        self.one_megabyte = 1024 * 1024  # in Bytes
-        self.ten_megabytes = 10 * self.one_megabyte
-        base_dir = dirname(abspath(__file__)) + sep
-        cvf = open(base_dir + "ciphertexts.csv", "r")
-        ciphertxt_reader = reader(cvf, dialect="excel")
-        self.ciphertexts = []
-        for row in ciphertxt_reader:
-            self.ciphertexts.append(row)
-        cvf.close()
-        self.ciphertext = a2b_hex(bytes(self.ciphertexts[1][5].encode('ascii')))
-
-    def test_encrypt_decrypt(self):
-        """Test encrypt for simple encryption and decryption"""
-        s = scrypt.encrypt(self.input, self.password, 0.1)
-        m = scrypt.decrypt(s, self.password)
-        self.assertEqual(m, self.input)
-
-    def test_encrypt(self):
-        """Test encrypt takes input and password strings as
-        positional arguments and produces ciphertext"""
-        s = scrypt.encrypt(self.input, self.password)
-        self.assertEqual(len(s), 128 + len(self.input))
-
-    def test_encrypt_input_and_password_as_keywords(self):
-        """Test encrypt for input and password accepted as keywords"""
-        s = scrypt.encrypt(password=self.password, input=self.input)
-        m = scrypt.decrypt(s, self.password)
-        self.assertEqual(m, self.input)
-
-    def test_encrypt_missing_input_keyword_argument(self):
-        """Test encrypt raises TypeError if keyword argument missing input"""
-        self.assertRaises(TypeError, lambda: scrypt.encrypt(password=self.password))
-
-    def test_encrypt_missing_password_positional_argument(self):
-        """Test encrypt raises TypeError if second positional argument missing
-        (password)"""
-        self.assertRaises(TypeError, lambda: scrypt.encrypt(self.input))
-
-    def test_encrypt_missing_both_required_positional_arguments(self):
-        """Test encrypt raises TypeError if both positional arguments missing
-        (input and password)"""
-        self.assertRaises(TypeError, lambda: scrypt.encrypt())
-
-    def test_encrypt_maxtime_positional(self):
-        """Test encrypt maxtime accepts maxtime at position 3"""
-        s = scrypt.encrypt(self.input, self.password, 0.01)
-        m = scrypt.decrypt(s, self.password)
-        self.assertEqual(m, self.input)
-
-    def test_encrypt_maxtime_key(self):
-        """Test encrypt maxtime accepts maxtime as keyword argument"""
-        s = scrypt.encrypt(self.input, self.password, maxtime=0.01)
-        m = scrypt.decrypt(s, self.password)
-        self.assertEqual(m, self.input)
-
-    def test_encrypt_maxmem_positional(self):
-        """Test encrypt maxmem accepts 4th positional argument and exactly
-        (1 megabyte) of storage to use for V array"""
-        s = scrypt.encrypt(self.input, self.password, 0.01, self.one_megabyte)
-        m = scrypt.decrypt(s, self.password)
-        self.assertEqual(m, self.input)
-
-    def test_encrypt_maxmem_undersized(self):
-        """Test encrypt maxmem accepts (< 1 megabyte) of storage to use for V array"""
-        s = scrypt.encrypt(self.input, self.password, 0.01, self.one_byte)
-        m = scrypt.decrypt(s, self.password)
-        self.assertEqual(m, self.input)
-
-    def test_encrypt_maxmem_in_normal_range(self):
-        """Test encrypt maxmem accepts (> 1 megabyte) of storage to use for V array"""
-        s = scrypt.encrypt(self.input,
-                           self.password,
-                           0.01,
-                           self.ten_megabytes)
-        m = scrypt.decrypt(s, self.password)
-        self.assertEqual(m, self.input)
-
-    def test_encrypt_maxmem_keyword_argument(self):
-        """Test encrypt maxmem accepts exactly (1 megabyte) of storage to use for
-        V array"""
-        s = scrypt.encrypt(self.input,
-                           self.password,
-                           maxmem=self.one_megabyte,
-                           maxtime=0.01)
-        m = scrypt.decrypt(s, self.password)
-        self.assertEqual(m, self.input)
-
-    def test_encrypt_maxmemfrac_positional(self):
-        """Test encrypt maxmemfrac accepts 5th positional argument of 1/16 total
-        memory for V array"""
-        s = scrypt.encrypt(self.input, self.password, 0.01, 0, 0.0625)
-        m = scrypt.decrypt(s, self.password)
-        self.assertEqual(m, self.input)
-
-    def test_encrypt_maxmemfrac_keyword_argument(self):
-        """Test encrypt maxmemfrac accepts keyword argument of 1/16 total memory for
-        V array"""
-        s = scrypt.encrypt(self.input, self.password, maxmemfrac=0.0625,
-                           maxtime=0.01)
-        m = scrypt.decrypt(s, self.password)
-        self.assertEqual(m, self.input)
-
-    def test_encrypt_long_input(self):
-        """Test encrypt accepts long input for encryption"""
-        s = scrypt.encrypt(self.longinput, self.password, 0.1)
-        self.assertEqual(len(s), 128 + len(self.longinput))
-
-    def test_encrypt_raises_error_on_invalid_keyword(self):
-        """Test encrypt raises TypeError if invalid keyword used in argument"""
-        self.assertRaises(TypeError, lambda: scrypt.encrypt(self.input,
-            self.password, nonsense="Raise error"))
-
-    def test_decrypt_from_csv_ciphertexts(self):
-        """Test decrypt function with precalculated combinations"""
-        for row in self.ciphertexts[1:]:
-            h = scrypt.decrypt(a2b_hex(bytes(row[5].encode('ascii'))), row[1])
-            self.assertEqual(bytes(h.encode("ascii")), row[0].encode("ascii"))
-
-    def test_decrypt_maxtime_positional(self):
-        """Test decrypt function accepts third positional argument"""
-        m = scrypt.decrypt(self.ciphertext, self.password, self.five_seconds)
-        self.assertEqual(m, self.input)
-
-    def test_decrypt_maxtime_keyword_argument(self):
-        """Test decrypt function accepts maxtime keyword argument"""
-        m = scrypt.decrypt(maxtime=1.0, input=self.ciphertext, password=self.password)
-        self.assertEqual(m, self.input)
-
-    def test_decrypt_maxmem_positional(self):
-        """Test decrypt function accepts fourth positional argument"""
-        m = scrypt.decrypt(self.ciphertext, self.password, self.five_minutes, self.ten_megabytes)
-        self.assertEqual(m, self.input)
-
-    def test_decrypt_maxmem_keyword_argument(self):
-        """Test decrypt function accepts maxmem keyword argument"""
-        m = scrypt.decrypt(maxmem=self.ten_megabytes, input=self.ciphertext, password=self.password)
-        self.assertEqual(m, self.input)
-
-    def test_decrypt_maxmemfrac_positional(self):
-        """Test decrypt function accepts maxmem keyword argument"""
-        m = scrypt.decrypt(self.ciphertext, self.password, self.five_minutes, self.one_megabyte, 0.0625)
-        self.assertEqual(m, self.input)
-
-    def test_decrypt_maxmemfrac_keyword_argument(self):
-        """Test decrypt function accepts maxmem keyword argument"""
-        m = scrypt.decrypt(maxmemfrac=0.625, input=self.ciphertext, password=self.password)
-        self.assertEqual(m, self.input)
-
-    def test_decrypt_raises_error_on_too_little_time(self):
-        """Test decrypt function raises scrypt.error raised if insufficient time allowed for
-        ciphertext decryption"""
-        s = scrypt.encrypt(self.input, self.password, 0.1)
-        self.assertRaises(scrypt.error,
-                          lambda: scrypt.decrypt(s, self.password, .01))
-
-
-class TestScryptHash(testm.TestCase):
-
-    def setUp(self):
-        self.input = "message"
-        self.password = "password"
-        self.salt = "NaCl"
-        self.hashes = []
-        base_dir = dirname(abspath(__file__)) + sep
-        hvf = open(base_dir + "hashvectors.csv", "r")
-        hash_reader = reader(hvf, dialect="excel")
-        for row in hash_reader:
-            self.hashes.append(row)
-        hvf.close()
-
-    def test_hash_vectors_from_csv(self):
-        """Test hash function with precalculated combinations"""
-        for row in self.hashes[1:]:
-            h = scrypt.hash(row[0], row[1], int(row[2]), int(row[3]), int(row[4]))
-            hhex = b2a_hex(h)
-            self.assertEqual(hhex, bytes(row[5].encode("utf-8")))
-
-    def test_hash_buflen_keyword(self):
-        """Test hash takes keyword valid buflen"""
-        h64 = scrypt.hash(self.input, self.salt, buflen=64)
-        h128 = scrypt.hash(self.input, self.salt, buflen=128)
-        self.assertEqual(len(h64), 64)
-        self.assertEqual(len(h128), 128)
-
-    def test_hash_n_positional(self):
-        """Test hash accepts valid N in position 3"""
-        h = scrypt.hash(self.input, self.salt, 256)
-        self.assertEqual(len(h), 64)
-
-    def test_hash_n_keyword(self):
-        """Test hash takes keyword valid N"""
-        h = scrypt.hash(N=256, password=self.input, salt=self.salt)
-        self.assertEqual(len(h), 64)
-
-    def test_hash_r_positional(self):
-        """Test hash accepts valid r in position 4"""
-        h = scrypt.hash(self.input, self.salt, 256, 16)
-        self.assertEqual(len(h), 64)
-
-    def test_hash_r_keyword(self):
-        """Test hash takes keyword valid r"""
-        h = scrypt.hash(r=16, password=self.input, salt=self.salt)
-        self.assertEqual(len(h), 64)
-
-    def test_hash_p_positional(self):
-        """Test hash accepts valid p in position 5"""
-        h = scrypt.hash(self.input, self.salt, 256, 8, 2)
-        self.assertEqual(len(h), 64)
-
-    def test_hash_p_keyword(self):
-        """Test hash takes keyword valid p"""
-        h = scrypt.hash(p=4, password=self.input, salt=self.salt)
-        self.assertEqual(len(h), 64)
-
-    def test_hash_raises_error_on_p_equals_zero(self):
-        """Test hash raises scrypt error on illegal parameter value (p = 0)"""
-        self.assertRaises(scrypt.error,
-                          lambda: scrypt.hash(self.input, self.salt, p=0))
-
-    def test_hash_raises_error_on_negative_p(self):
-        """Test hash raises scrypt error on illegal parameter value (p < 0)"""
-        self.assertRaises(scrypt.error,
-                          lambda: scrypt.hash(self.input, self.salt, p=-1))
-
-    def test_hash_raises_error_on_r_equals_zero(self):
-        """Test hash raises scrypt error on illegal parameter value (r = 0)"""
-        self.assertRaises(scrypt.error,
-                          lambda: scrypt.hash(self.input, self.salt, r=0))
-
-    def test_hash_raises_error_on_negative_r(self):
-        """Test hash raises scrypt error on illegal parameter value (r < 1)"""
-        self.assertRaises(scrypt.error,
-                          lambda: scrypt.hash(self.input, self.salt, r=-1))
-
-    def test_hash_raises_error_r_p_over_limit(self):
-        """Test hash raises scrypt error when parameters r multiplied by p over limit 2**30"""
-        self.assertRaises(scrypt.error,
-                          lambda: scrypt.hash(self.input, self.salt, r=2, p=2 ** 29))
-
-    def test_hash_raises_error_n_not_power_of_two(self):
-        """Test hash raises scrypt error when parameter N is not a power of two {2, 4, 8, 16, etc}"""
-        self.assertRaises(scrypt.error,
-                          lambda: scrypt.hash(self.input, self.salt, N=3))
-
-    def test_hash_raises_error_n_under_limit(self):
-        """Test hash raises scrypt error when parameter N under limit of 1"""
-        self.assertRaises(scrypt.error,
-                          lambda: scrypt.hash(self.input, self.salt, N=1))
-        self.assertRaises(scrypt.error,
-                          lambda: scrypt.hash(self.input, self.salt, N=-1))
-
-if __name__ == "__main__":
-    testm.main()
diff -pruN 0.8.0-0.3/tests/test_scrypt_py2x.py 0.8.20-1/tests/test_scrypt_py2x.py
--- 0.8.0-0.3/tests/test_scrypt_py2x.py	2015-07-05 09:28:05.000000000 +0000
+++ 0.8.20-1/tests/test_scrypt_py2x.py	1970-01-01 00:00:00.000000000 +0000
@@ -1,52 +0,0 @@
-# -*- coding: utf-8 -*-
-
-from sys import version_info, exit
-
-import scrypt
-
-if ((version_info > (3, 2, 0, 'final', 0)) or
-        (version_info > (2, 7, 0, 'final', 0) and
-         version_info < (3, 0, 0, 'final', 0))):
-    import unittest as testm
-else:
-    try:
-        import unittest2 as testm
-    except ImportError:
-        print("Please install unittest2 to run the test suite")
-        exit(-1)
-
-
-@testm.skipIf(version_info > (3, 0, 0, 'final', 0), "Tests for Python 2 only")
-class TestScryptForPython2(testm.TestCase):
-
-    def setUp(self):
-        self.input = "message"
-        self.password = "password"
-        self.unicode_text = '\xe1\x93\x84\xe1\x93\x87\xe1\x95\x97\xe1\x92\xbb\xe1\x92\xa5\xe1\x90\x85\xe1\x91\xa6'.decode('utf-8')
-
-    def test_py2_encrypt_fails_on_unicode_input(self):
-        """Test Py2 encrypt raises TypeError when Unicode input passed"""
-        self.assertRaises(TypeError, lambda: scrypt.encrypt(self.unicode_text, self.password))
-
-    def test_py2_encrypt_fails_on_unicode_password(self):
-        """Test Py2 encrypt raises TypeError when Unicode password passed"""
-        self.assertRaises(TypeError, lambda: scrypt.encrypt(self.input, self.unicode_text))
-
-    def test_py2_encrypt_returns_string(self):
-        """Test Py2 encrypt returns str"""
-        e = scrypt.encrypt(self.input, self.password, 0.1)
-        self.assertTrue(isinstance(e, str))
-
-    def test_py2_decrypt_returns_string(self):
-        """Test Py2 decrypt returns str"""
-        s = scrypt.encrypt(self.input, self.password, 0.1)
-        m = scrypt.decrypt(s, self.password)
-        self.assertTrue(isinstance(m, str))
-
-    def test_py2_hash_returns_string(self):
-        """Test Py2 hash return str"""
-        h = scrypt.hash(self.input, self.password)
-        self.assertTrue(isinstance(h, str))
-
-if __name__ == "__main__":
-    testm.main()
diff -pruN 0.8.0-0.3/tests/test_scrypt_py3x.py 0.8.20-1/tests/test_scrypt_py3x.py
--- 0.8.0-0.3/tests/test_scrypt_py3x.py	2015-07-05 09:28:14.000000000 +0000
+++ 0.8.20-1/tests/test_scrypt_py3x.py	1970-01-01 00:00:00.000000000 +0000
@@ -1,57 +0,0 @@
-# -*- coding: utf-8 -*-
-
-from sys import version_info, exit
-
-import scrypt
-
-if ((version_info > (3, 2, 0, 'final', 0)) or
-        (version_info > (2, 7, 0, 'final', 0) and
-         version_info < (3, 0, 0, 'final', 0))):
-    import unittest as testm
-else:
-    try:
-        import unittest2 as testm
-    except ImportError:
-        print("Please install unittest2 to run the test suite")
-        exit(-1)
-
-
-@testm.skipIf(version_info < (3, 0, 0, 'final', 0), "Tests for Python 3 only")
-class TestScryptForPy3(testm.TestCase):
-
-    def setUp(self):
-        self.input = "message"
-        self.password = "password"
-        self.byte_text = b'\xe1\x93\x84\xe1\x93\x87\xe1\x95\x97\xe1\x92\xbb\xe1\x92\xa5\xe1\x90\x85\xe1\x91\xa6'
-        self.unicode_text = self.byte_text.decode('utf-8', "strict")
-
-    def test_py3_encrypt_allows_bytes_input(self):
-        """Test Py3 encrypt allows unicode input"""
-        s = scrypt.encrypt(self.byte_text, self.password, 0.1)
-        m = scrypt.decrypt(s, self.password)
-        self.assertEqual(bytes(m.encode("utf-8")), self.byte_text)
-
-    def test_py3_encrypt_allows_bytes_password(self):
-        """Test Py3 encrypt allows unicode password"""
-        s = scrypt.encrypt(self.input, self.byte_text, 0.1)
-        m = scrypt.decrypt(s, self.byte_text)
-        self.assertEqual(m, self.input)
-
-    def test_py3_encrypt_returns_bytes(self):
-        """Test Py3 encrypt return bytes"""
-        s = scrypt.encrypt(self.input, self.password, 0.1)
-        self.assertTrue(isinstance(s, bytes))
-
-    def test_py3_decrypt_returns_unicode_string(self):
-        """Test Py3 decrypt returns Unicode UTF-8 string"""
-        s = scrypt.encrypt(self.input, self.password, 0.1)
-        m = scrypt.decrypt(s, self.password)
-        self.assertTrue(isinstance(m, str))
-
-    def test_py3_hash_returns_bytes(self):
-        """Test Py3 hash return bytes"""
-        h = scrypt.hash(self.input, self.password)
-        self.assertTrue(isinstance(h, bytes))
-
-if __name__ == "__main__":
-    testm.main()
diff -pruN 0.8.0-0.3/tox.ini 0.8.20-1/tox.ini
--- 0.8.0-0.3/tox.ini	1970-01-01 00:00:00.000000000 +0000
+++ 0.8.20-1/tox.ini	2022-02-21 10:55:27.000000000 +0000
@@ -0,0 +1,14 @@
+[tox]
+minversion = 2.4
+envlist = py27,pypy,py34,py35,py36,py37,py38,py39,docs,pep8,py3pep8
+
+[testenv]
+extras =
+   test
+commands = setup.py test
+
+
+[pep8]
+max_line_length = 80
+statistics = True
+ignore = E121,E122,E123,E125,E126,E127,E128,E226,E231,E501,E712
diff -pruN 0.8.0-0.3/travis/build-wheels.sh 0.8.20-1/travis/build-wheels.sh
--- 0.8.0-0.3/travis/build-wheels.sh	1970-01-01 00:00:00.000000000 +0000
+++ 0.8.20-1/travis/build-wheels.sh	2022-02-21 10:55:27.000000000 +0000
@@ -0,0 +1,32 @@
+#!/bin/bash
+set -e -x
+
+function repair_wheel {
+    wheel="$1"
+    if ! auditwheel show "$wheel"; then
+        echo "Skipping non-platform wheel $wheel"
+    else
+        auditwheel repair "$wheel" --plat "$PLAT" -w /io/wheelhouse/
+    fi
+}
+
+
+# Install a system package required by our library
+yum install -y openssl-devel
+
+# Compile wheels
+for PYBIN in /opt/python/*/bin; do
+    "${PYBIN}/pip" install -r /io/dev-requirements.txt
+    "${PYBIN}/pip" wheel /io/ --no-deps -w wheelhouse/
+done
+
+# Bundle external shared libraries into the wheels
+for whl in wheelhouse/*.whl; do
+    repair_wheel "$whl"
+done
+
+# Install packages and test
+for PYBIN in /opt/python/*/bin/; do
+    "${PYBIN}/pip" install scrypt --no-index -f /io/wheelhouse
+    (cd "$HOME"; "${PYBIN}/pytest" --pyargs scrypt)
+done
diff -pruN 0.8.0-0.3/.travis.yml 0.8.20-1/.travis.yml
--- 0.8.0-0.3/.travis.yml	1970-01-01 00:00:00.000000000 +0000
+++ 0.8.20-1/.travis.yml	2022-02-21 10:55:27.000000000 +0000
@@ -0,0 +1,183 @@
+# After changing this file, check it on:
+#   http://lint.travis-ci.org/
+language: python
+
+matrix:
+  include:
+    - sudo: required
+      services:
+        - docker
+      env: DOCKER_IMAGE=quay.io/pypa/manylinux1_x86_64
+           PLAT=manylinux1_x86_64
+           MANYLINUX=1
+    - sudo: required
+      services:
+        - docker
+      env: DOCKER_IMAGE=quay.io/pypa/manylinux1_i686
+           PRE_CMD=linux32
+           PLAT=manylinux1_i686
+           MANYLINUX=1
+    - sudo: required
+      services:
+        - docker
+      env: DOCKER_IMAGE=quay.io/pypa/manylinux2010_x86_64
+           PLAT=manylinux2010_x86_64
+           MANYLINUX=1
+    - sudo: required
+      arch: arm64-graviton2
+      group: edge
+      virt: lxd
+      services:
+        - docker
+      env: DOCKER_IMAGE=quay.io/pypa/manylinux2014_aarch64
+           PLAT=manylinux2014_aarch64
+           MANYLINUX=1
+    - os: linux
+      python: 2.7
+      env:
+        - PYFLAKES=1
+        - PEP8=1
+        - MANYLINUX=0
+      before_install:
+        - pip install pep8==1.6.2
+        - pip install pyflakes
+      script:
+        - PYFLAKES_NODOCTEST=1 pyflakes scrypt.py | grep -E -v 'unable to detect undefined names|assigned to but never used|imported but unused|redefinition of unused' > test.out; cat test.out; test \! -s test.out
+        - pep8 scrypt
+    - os: linux
+      python: 3.6
+      env:
+        - TOXENV=py36
+        - MANYLINUX=0
+    - os: linux
+      python: 3.6
+      env:
+        - USE_WHEEL=1
+        - LINUX_WHEEL=1
+        - TOXENV=py36
+        - MANYLINUX=0
+#      addons:
+#        apt:
+#          packages:
+#            - patchelf
+    - os: linux
+      python: 3.6
+      env:
+        - USE_SDIST=1
+        - TOXENV=py36
+        - MANYLINUX=0
+    - os: osx
+      osx_image: xcode10.2
+      language: objective-c
+      env:
+        - USE_WHEEL=1
+        - TRAVIS_PYTHON_VERSION=3.6
+        - MAC_WHEEL=1
+        - MANYLINUX=0
+        - TOXENV=py36
+        - SCRYPT_SUPPRESS_LINK_FLAGS=1
+    - os: osx
+      osx_image: xcode10.2
+      language: objective-c
+      env:
+        - USE_WHEEL=1
+        - TRAVIS_PYTHON_VERSION=3.7
+        - MAC_WHEEL=1
+        - MANYLINUX=0
+        - TOXENV=py37
+        - SCRYPT_SUPPRESS_LINK_FLAGS=1
+    - os: osx
+      osx_image: xcode10.2
+      language: objective-c
+      env:
+        - USE_WHEEL=1
+        - TRAVIS_PYTHON_VERSION=3.8
+        - MAC_WHEEL=1
+        - MANYLINUX=0
+        - TOXENV=py38
+        - SCRYPT_SUPPRESS_LINK_FLAGS=1
+    - os: osx
+      osx_image: xcode11.6
+      language: objective-c
+      env:
+        - USE_WHEEL=1
+        - TRAVIS_PYTHON_VERSION=3.9
+        - MAC_WHEEL=1
+        - MANYLINUX=0
+        - TOXENV=py39
+        - SCRYPT_SUPPRESS_LINK_FLAGS=1
+
+cache: pip
+
+before_install:
+  - uname -a
+  - df -h
+  - ulimit -a
+  - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then source util/travis_osx_install.sh; fi
+  - ccache -s
+  - |
+    if [ "${MANYLINUX}" == "0" ]; then
+        which python; python --version
+        pip install --upgrade pip
+        pip install --upgrade wheel
+        mkdir ${TRAVIS_BUILD_DIR}/wheelhouse
+        pip install --upgrade auditwheel
+    else
+        docker pull $DOCKER_IMAGE
+    fi
+  # Set numpy version first, other packages link against it
+  #- pip install Cython matplotlib nose coverage codecov futures
+  - set -o pipefail
+
+script:
+  # Define a fixed build dir so next step works
+  - |
+    if [ "${LINUX_WHEEL}" == "1" ]; then
+        pip wheel . -v
+    fi
+  - |
+    if [ "${MAC_WHEEL}" == "1" ]; then
+       export LDFLAGS="/usr/local/opt/openssl\@1.1/lib/libssl.a /usr/local/opt/openssl\@1.1/lib/libcrypto.a"
+       export CFLAGS="-I/usr/local/opt/openssl\@1.1/include"
+       pip wheel . -v
+       delocate-listdeps scrypt*.whl
+       delocate-wheel -v scrypt*.whl
+       delocate-listdeps --all scrypt*.whl
+    fi
+  - |
+#    if [ "${LINUX_WHEEL}" == "1" ]; then
+#       auditwheel show scrypt*.whl
+#       auditwheel repair scrypt*.whl
+#    fi
+  - |
+    if [ "${MANYLINUX}" == "1" ]; then
+        docker run --rm -e PLAT=$PLAT -v `pwd`:/io $DOCKER_IMAGE $PRE_CMD /io/travis/build-wheels.sh
+    elif [ "${USE_WHEEL}" == "1" ]; then
+        # Need verbose output or TravisCI will terminate after 10 minutes
+        #pip wheel . -v
+        cp *.whl ${TRAVIS_BUILD_DIR}/wheelhouse/
+        pip install scrypt*.whl -v
+        python setup.py test
+    elif [ "${USE_SDIST}" == "1" ]; then
+        python setup.py sdist
+        # Move out of source directory to avoid finding local scrypt
+        pushd dist
+        pip install scrypt* -v
+        popd
+        python setup.py test
+    else
+        #CFLAGS="--coverage" python setup.py build --build-lib build/lib/ --build-temp build/tmp/
+        python setup.py build
+        python setup.py test
+    fi
+
+deploy:
+  provider: releases
+  api-key:
+    secure: "Xv8A881fwJ44B3u7PYnouvVKeexqdSPDL5wQe98SeVNT7+gaPINiSPiTQc8Pr8K0rMogYVkC6m+2Q1G+YOZJz9k2LBhX1pdgGi8qUk9Zq59UVLwWH8tHs6yyXdu+AvKrxZaOmfsDDdilJknYBaiH9GO13TX+IiTqixt6iJNFMU6HqR0aaqIXi6ZhSNTLRjODEXRfUovJiCqppo9fcfbQC4Fos1fzlaGc5ccLy+VwEzYyLY7EgLrbZkFrvJSrDD5VJnZ/yuKD9FIvog5vyUE0BMs0eRtd5R1q6e1xtTyNArZa86OXfOzIj1vgkrq6JVnXBnFX7NdmBRhocwW6WByZ2ucd7+Za1w+NrS5sRRcTSfpfjUMx8AwUMIXJ9wj3RzTvaK6+/58ScgxrMZVGc4luT4NUaVjowMt86PVWfMCFtGKRBIYD+il9G9I1hjFQtkFX0EaZ2v2tQbiL+J1rHEkVnMDJ8hVatpLZFQ45/91/sVw8rkNZjQE1z7psKS9KPpEPt2Kvfao9G7Lnj4n42PgaM+VTeVWgUiNs3g8qj+04IsBxXGX+/iRlZUOMOWg0EmeGqBjz4RftGRkuWh7fMxF9uTHpXWWuFUH8iNL/Lkb2cNIpobzLCG8qtUhe2LdRfT2De/6s6tlnEh72zaQEtXETatgtDCdiurpnBQxV5DVSuuU="
+  file_glob: true
+  file: ${TRAVIS_BUILD_DIR}/wheelhouse/*
+  skip_cleanup: true
+  draft: true
+  on:
+    tags: true
diff -pruN 0.8.0-0.3/util/run.sh 0.8.20-1/util/run.sh
--- 0.8.0-0.3/util/run.sh	1970-01-01 00:00:00.000000000 +0000
+++ 0.8.20-1/util/run.sh	2022-02-21 10:55:27.000000000 +0000
@@ -0,0 +1,42 @@
+#!/bin/bash
+
+set -e
+set -x
+
+if [[ "$(uname -s)" == "Darwin" ]]; then
+    # initialize our pyenv
+    PYENV_ROOT="$HOME/.pyenv"
+    PATH="$PYENV_ROOT/bin:$PATH"
+    eval "$(pyenv init -)"
+
+    # set our flags to use homebrew openssl
+    # if the build is static we need different LDFLAGS
+    if [[ "${SCRYPT_SUPPRESS_LINK_FLAGS}" == "1" ]]; then
+        export LDFLAGS="/usr/local/opt/openssl\@1.1/lib/libssl.a /usr/local/opt/openssl\@1.1/lib/libcrypto.a"
+        export CFLAGS="-I/usr/local/opt/openssl\@1.1/include"
+    else
+        # Compile the dynamic link build against 1.0.2 because the linker refuses to properly load 1.1.0
+        export LDFLAGS="-L/usr/local/opt/openssl/lib"
+        export CFLAGS="-I/usr/local/opt/openssl/include"
+    fi
+else
+    if [[ "${TOXENV}" == "pypy" ]]; then
+        PYENV_ROOT="$HOME/.pyenv"
+        PATH="$PYENV_ROOT/bin:$PATH"
+        eval "$(pyenv init -)"
+    fi
+    if [ -n "${OPENSSL}" ]; then
+        OPENSSL_DIR="ossl-1/${OPENSSL}"
+
+        export PATH="$HOME/$OPENSSL_DIR/bin:$PATH"
+        export CFLAGS="-I$HOME/$OPENSSL_DIR/include"
+        # rpath on linux will cause it to use an absolute path so we don't need to do LD_LIBRARY_PATH
+        export LDFLAGS="-L$HOME/$OPENSSL_DIR/lib -Wl,-rpath=$HOME/$OPENSSL_DIR/lib"
+    fi
+fi
+source ~/.venv/bin/activate
+#tox
+# Output information about linking of the OpenSSL library on OS X
+if [[ "$(uname -s)" == "Darwin" ]]; then
+    otool -L $(find .tox -name "_openssl*.so")
+fi
diff -pruN 0.8.0-0.3/util/travis_linux_install.sh 0.8.20-1/util/travis_linux_install.sh
--- 0.8.0-0.3/util/travis_linux_install.sh	1970-01-01 00:00:00.000000000 +0000
+++ 0.8.20-1/util/travis_linux_install.sh	2022-02-21 10:55:27.000000000 +0000
@@ -0,0 +1,5 @@
+#!/bin/bash
+pip install --upgrade pip
+pip install --upgrade wheel
+pip install tox
+pip install --upgrade auditwheel
diff -pruN 0.8.0-0.3/util/travis_osx_install.sh 0.8.20-1/util/travis_osx_install.sh
--- 0.8.0-0.3/util/travis_osx_install.sh	1970-01-01 00:00:00.000000000 +0000
+++ 0.8.20-1/util/travis_osx_install.sh	2022-02-21 10:55:27.000000000 +0000
@@ -0,0 +1,71 @@
+#!/bin/bash
+brew update
+brew install ccache
+brew outdated openssl || brew upgrade openssl
+brew install openssl@1.1
+
+export CFLAGS="-I$(brew --prefix openssl)/include $CFLAGS"
+export LDFLAGS="-L$(brew --prefix openssl)/lib $LDFLAGS"
+
+# install pyenv
+git clone --depth 1 https://github.com/pyenv/pyenv ~/.pyenv
+PYENV_ROOT="$HOME/.pyenv"
+PATH="$PYENV_ROOT/bin:$PATH"
+eval "$(pyenv init -)"
+
+case "${TOXENV}" in
+	py27)
+		curl -O https://bootstrap.pypa.io/get-pip.py
+		python get-pip.py --user
+		;;
+	py33)
+		pyenv install 3.3.6
+		pyenv global 3.3.6
+		;;
+	py34)
+		pyenv install 3.4.6
+		pyenv global 3.4.6
+		;;
+	py35)
+		pyenv install 3.5.3
+		pyenv global 3.5.3
+		;;
+	py36)
+		pyenv install 3.6.1
+		pyenv global 3.6.1
+		;;
+	py37)
+		pyenv install 3.7.2
+		pyenv global 3.7.2
+		;;
+	py38)
+		pyenv install 3.8.0
+		pyenv global 3.8.0
+		;;
+	py39)
+		pyenv install 3.9.0
+		pyenv global 3.9.0
+		;;
+	pypy*)
+		pyenv install "$PYPY_VERSION"
+		pyenv global "$PYPY_VERSION"
+		;;
+	pypy3)
+		pyenv install pypy3-2.4.0
+		pyenv global pypy3-2.4.0
+		;;
+	docs)
+		brew install enchant
+		curl -O https://bootstrap.pypa.io/get-pip.py
+		python get-pip.py --user
+		;;
+esac
+pyenv rehash
+python -m pip install --user virtualenv
+python -m virtualenv ~/.venv
+source ~/.venv/bin/activate
+# This coverage pin must be kept in sync with tox.ini
+pip install --upgrade pip
+pip install --upgrade wheel
+pip install tox
+pip install delocate 
