mirror of
https://github.com/LBRYFoundation/pool.git
synced 2025-08-23 17:37:25 +00:00
Merge pull request #14 from lbryio/next
Update Yiimp Live Branch that gets pulled to installs
This commit is contained in:
commit
a9dd7f7ac2
2381 changed files with 31671 additions and 10052 deletions
5
.gitignore
vendored
5
.gitignore
vendored
|
@ -1,5 +1,7 @@
|
|||
*.o
|
||||
*.a
|
||||
.deps
|
||||
.dirstamp
|
||||
stratum/stratum
|
||||
stratum/blocknotify
|
||||
blocknotify/blocknotify
|
||||
|
@ -18,3 +20,6 @@ web/serverconfig.php
|
|||
web/assets/
|
||||
*.rej
|
||||
*.orig
|
||||
.idea/*
|
||||
web/yaamp/.idea/
|
||||
*.0
|
||||
|
|
5
.travis.yml.disable
Normal file
5
.travis.yml.disable
Normal file
|
@ -0,0 +1,5 @@
|
|||
language: cpp
|
||||
script:
|
||||
- (cd blocknotify && make)
|
||||
- (cd stratum/iniparser && make)
|
||||
- (cd stratum && make)
|
10
LICENSE
Normal file
10
LICENSE
Normal file
|
@ -0,0 +1,10 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016-2018 LBRY Inc
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish,distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
116
README.md
116
README.md
|
@ -1,90 +1,65 @@
|
|||
#yiimp - yaamp fork
|
||||
|
||||
Required:
|
||||
|
||||
linux, mysql, php, memcached, a webserver (lighttpd or nginx recommended)
|
||||
# Lbry Mining Pool based on Yiimp
|
||||
|
||||
|
||||
Config for nginx:
|
||||
|
||||
location / {
|
||||
try_files $uri @rewrite;
|
||||
}
|
||||
|
||||
location @rewrite {
|
||||
rewrite ^/(.*)$ /index.php?r=$1;
|
||||
}
|
||||
|
||||
location ~ \.php$ {
|
||||
fastcgi_pass unix:/var/run/php5-fpm.sock;
|
||||
fastcgi_index index.php;
|
||||
include fastcgi_params;
|
||||
}
|
||||
### TODO: Rewrite this README, Rewrite Install Script to be more logical, Do it all again to document the hax. Be sure to rewrite things to use TMUX and document as such.
|
||||
|
||||
|
||||
If you use apache, it should be something like that (already set in web/.htaccess):
|
||||
## Prerequisites:
|
||||
1. Ubuntu 18.04
|
||||
2. Install Script (Provided in this repo)
|
||||
|
||||
RewriteEngine on
|
||||
WARNINGS
|
||||
- Use at your own risks.
|
||||
|
||||
RewriteCond %{REQUEST_FILENAME} !-f
|
||||
RewriteRule ^(.*) index.php?r=$1 [QSA]
|
||||
The install Script will install the pool and all dependencies needed.
|
||||
|
||||
TO INSTALL:
|
||||
1. Log in to your server
|
||||
2. Create new user - sudo adduser (username)
|
||||
3. Add user to sudo group - sudo adduser (username) sudo
|
||||
4. Log in to new user - sudo su (username)
|
||||
5. cd ~/
|
||||
6. `wget https://raw.githubusercontent.com/lbryio/pool/next/install.sh && chmod +x install.sh && ./install.sh`
|
||||
7. Follow the instructions on the screen.
|
||||
8. sudo bash pool-start.sh
|
||||
|
||||
If you use lighttpd, use the following config:
|
||||
|
||||
$HTTP["host"] =~ "yiimp.ccminer.org" {
|
||||
server.document-root = "/var/yaamp/web"
|
||||
url.rewrite-if-not-file = (
|
||||
"^(.*)/([0-9]+)$" => "index.php?r=$1&id=$2",
|
||||
"^(.*)\?(.*)" => "index.php?r=$1&$2",
|
||||
"^(.*)" => "index.php?r=$1",
|
||||
"." => "index.php"
|
||||
)
|
||||
|
||||
url.access-deny = ( "~", ".dat", ".log" )
|
||||
}
|
||||
|
||||
|
||||
For the database, import the initial dump present in the sql/ folder
|
||||
|
||||
Then, apply the migration scripts to be in sync with the current git, they are sorted by date of change.
|
||||
|
||||
Your database need at least 2 users, one for the web site (php) and one for the stratum connections (password set in config/algo.conf).
|
||||
|
||||
|
||||
|
||||
The recommended install folder for the stratum engine is /var/stratum. Copy all the .conf files, run.sh, the stratum binary and the blocknotify binary to this folder.
|
||||
|
||||
Some scripts are expecting the web folder to be /var/web. You can use directory symlinks...
|
||||
|
||||
|
||||
Add your exchange API public and secret keys in these two separated files:
|
||||
|
||||
/etc/yiimp/keys.php - fixed path in code
|
||||
web/serverconfig.php - use sample as base...
|
||||
This will setup the pool ready for coin daemons to be added.
|
||||
|
||||
You can find sample config files in web/serverconfig.sample.php and web/keys.sample.php
|
||||
|
||||
This web application includes some command line tools, add bin/ folder to your path and type "yiic" to list them, "yiic checkup" can help to test your initial setup.
|
||||
Future scripts and maybe the "cron" jobs will then use this yiic console interface.
|
||||
|
||||
You need at least three backend shells (in screen) running these scripts:
|
||||
You need at least three backend shells (in tmux) running these scripts:
|
||||
|
||||
web/main.sh
|
||||
web/loop2.sh
|
||||
web/block.sh
|
||||
|
||||
Start one stratum per algo using the run.sh script with the algo as parameter. For example, for x11:
|
||||
This is done running the pool-start.sh script in the home folder.
|
||||
|
||||
run.sh x11
|
||||
Now you will need to edit the coin in the admin panel, this will be http://IP/site/ADMIN_ADDRESS_USED_WHILE_INSTALLING then go to Coins on the headers, Find LBRY Credits and click LBC.
|
||||
|
||||
Edit each .conf file with proper values.
|
||||
Here you need to do the following:
|
||||
1. Edit algo to lbry
|
||||
2. Edit image to /images/coin-LBRY.png
|
||||
3. Edit Daemon information to the following:
|
||||
4. process name - lbrycrdd
|
||||
5. Conf.folder - .lbrycrd
|
||||
6. RPC Host - 127.0.0.1
|
||||
7. RPC User - This is the Username at the end of the install script.
|
||||
8. RPC Password - This is the Password at the end of the install script.
|
||||
9. RPC Type - POW
|
||||
10. Edit Settings and tick the following boxes:
|
||||
11. Enable
|
||||
12. Auto Ready
|
||||
13. Visable
|
||||
14. Installed
|
||||
15. Click Save
|
||||
|
||||
Look at rc.local, it starts all three backend shells and all stratum processes. Copy it to the /etc folder so that all screen shells are started at boot up.
|
||||
Once you have clicked save, you need to restart the lbry daemon in the VPS:
|
||||
1. lbrycrd-cli stop
|
||||
2. lbrycrdd -daemon
|
||||
|
||||
All your coin's config files need to blocknotify their corresponding stratum using something like:
|
||||
|
||||
blocknotify=blocknotify yaamp.com:port coinid %s
|
||||
At the moment you will find other wallets active, you can click the install tick box on all of the ones that you are not using. I will update this at some point to remove them when installing.
|
||||
|
||||
On the website, go to http://server.com/site/adminRights to login as admin. You have to change it to something different in the code (web/yaamp/modules/site/SiteController.php). A real admin login may be added later, but you can setup a password authentification with your web server, sample for lighttpd:
|
||||
|
||||
|
@ -114,13 +89,10 @@ There are logs generated in the /var/stratum folder and /var/log/stratum/debug.l
|
|||
More instructions coming as needed.
|
||||
|
||||
|
||||
There a lot of unused code in the php branch. Lot come from other projects I worked on and I've been lazy to clean it up before to integrate it to yaamp. It's mostly based on the Yii framework which implements a lightweight MVC.
|
||||
|
||||
http://www.yiiframework.com/
|
||||
|
||||
|
||||
Credits:
|
||||
|
||||
Thanks to globalzon to have released the initial Yaamp source code.
|
||||
|
||||
Thanks to tpruvot for updating the source code to yiimp.
|
||||
Thanks to oakey22 for customising this for Lbry.
|
||||
Thanks to Coolguy3289 for picking this project back up and getting the software compatible with lbrycrd again.
|
||||
|
||||
|
|
13
bin/kill_stratum
Executable file
13
bin/kill_stratum
Executable file
|
@ -0,0 +1,13 @@
|
|||
#!/bin/bash
|
||||
|
||||
PLINE=$(ps -ef | grep "stratum config/$1" | grep -v grep)
|
||||
if [ $? ]; then
|
||||
PS=$(echo $PLINE | cut -d ' ' -f 2)
|
||||
if [ $PS ]; then
|
||||
kill $PS
|
||||
echo "killed stratum process $PS"
|
||||
else
|
||||
echo "Process not found"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
|
@ -3,6 +3,6 @@
|
|||
ROOTDIR=/data/yiimp
|
||||
DIR=`pwd`
|
||||
|
||||
cd "$ROOTDIR/web" && php yaamp/yiic.php $*
|
||||
cd "$ROOTDIR/web" && php yaamp/yiic.php "$@"
|
||||
|
||||
cd $DIR
|
||||
|
|
|
@ -1,9 +1,14 @@
|
|||
OUT_GO=blocknotify-dcr
|
||||
OUTPUT=blocknotify-dcr
|
||||
ROOT=`pwd`
|
||||
|
||||
all:
|
||||
rm -f $(OUT_GO)
|
||||
go build
|
||||
rm -rf vendor
|
||||
glide install
|
||||
ln -s ../vendor vendor/src
|
||||
rm -f vendor/src/github.com/decred/dcrrpcclient/wallet.go
|
||||
GOPATH="$(GOPATH):$(ROOT)/vendor" go build
|
||||
|
||||
install: all
|
||||
strip -s $(OUT_GO)
|
||||
|
@ -11,3 +16,7 @@ install: all
|
|||
mv $(OUT_GO) ../bin/$(OUTPUT)
|
||||
sh -c "../bin/$(OUTPUT) &"
|
||||
|
||||
clean:
|
||||
rm -f $(OUT_GO)
|
||||
rm -rf vendor
|
||||
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
// Copyright (c) 2016 The btcsuite developers
|
||||
// Copyright (c) 2015-2016 The Decred developers
|
||||
// Use of this source code is governed by an ISC
|
||||
// license that can be found in the LICENSE file.
|
||||
// Copyright (c) 2015-2017 YiiMP
|
||||
|
||||
// Sample blocknofify tool compatible with decred
|
||||
// will call the standard blocknotify yiimp tool on new block event.
|
||||
// Sample blocknotify wrapper tool compatible with decred notifications
|
||||
// will call the standard bin/blocknotify yiimp tool on new block event.
|
||||
|
||||
// Note: this tool is connected directly to dcrd, not to the wallet!
|
||||
|
||||
package main
|
||||
|
||||
|
@ -13,20 +12,21 @@ import (
|
|||
"log"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"github.com/decred/dcrd/chaincfg/chainhash"
|
||||
"bytes" // dcrd > 0.6+
|
||||
"github.com/decred/dcrd/wire"
|
||||
|
||||
"github.com/decred/dcrrpcclient"
|
||||
// "github.com/decred/dcrutil"
|
||||
)
|
||||
|
||||
const (
|
||||
processName = "blocknotify" // set the full path if required
|
||||
stratumDest = "yaamp.com:5744" // stratum host:port
|
||||
stratumDest = "yaamp.com:3252" // stratum host:port
|
||||
coinId = "1574" // decred database coin id
|
||||
|
||||
walletUser = "yiimprpc"
|
||||
walletPass = "myDecredPassword"
|
||||
dcrdUser = "yiimprpc"
|
||||
dcrdPass = "myDcrdPassword"
|
||||
|
||||
debug = false
|
||||
)
|
||||
|
@ -37,27 +37,31 @@ func main() {
|
|||
// for notifications. See the documentation of the dcrrpcclient
|
||||
// NotificationHandlers type for more details about each handler.
|
||||
ntfnHandlers := dcrrpcclient.NotificationHandlers{
|
||||
OnBlockConnected: func(hash *chainhash.Hash, height int32, time time.Time, vb uint16) {
|
||||
|
||||
// Find the process path.
|
||||
str := hash.String()
|
||||
args := []string{ stratumDest, coinId, str }
|
||||
out, err := exec.Command(processName, args...).Output()
|
||||
if err != nil {
|
||||
log.Printf("err %s", err)
|
||||
} else if debug {
|
||||
log.Printf("out %s", out)
|
||||
}
|
||||
|
||||
if (debug) {
|
||||
log.Printf("Block connected: %s %d", hash, height)
|
||||
OnBlockConnected: func(blockHeader []byte, transactions [][]byte) {
|
||||
// log.Printf("Block bytes: %v %v", blockHeader, transactions)
|
||||
var bhead wire.BlockHeader
|
||||
err := bhead.Deserialize(bytes.NewReader(blockHeader))
|
||||
if err == nil {
|
||||
str := bhead.BlockHash().String();
|
||||
args := []string{ stratumDest, coinId, str }
|
||||
out, err := exec.Command(processName, args...).Output()
|
||||
if err != nil {
|
||||
log.Printf("err %s", err)
|
||||
} else if debug {
|
||||
log.Printf("out %s", out)
|
||||
}
|
||||
if (debug) {
|
||||
log.Printf("Block connected: %s", str)
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
}
|
||||
|
||||
// Connect to local dcrd RPC server using websockets.
|
||||
// dcrwHomeDir := dcrutil.AppDataDir("dcrwallet", false)
|
||||
// folder := dcrwHomeDir
|
||||
// dcrdHomeDir := dcrutil.AppDataDir("dcrd", false)
|
||||
// folder := dcrdHomeDir
|
||||
folder := ""
|
||||
certs, err := ioutil.ReadFile(filepath.Join(folder, "rpc.cert"))
|
||||
if err != nil {
|
||||
|
@ -66,11 +70,11 @@ func main() {
|
|||
}
|
||||
|
||||
connCfg := &dcrrpcclient.ConnConfig{
|
||||
Host: "127.0.0.1:15740",
|
||||
Host: "127.0.0.1:9109",
|
||||
Endpoint: "ws", // websocket
|
||||
|
||||
User: walletUser,
|
||||
Pass: walletPass,
|
||||
User: dcrdUser,
|
||||
Pass: dcrdPass,
|
||||
|
||||
DisableTLS: (certs == nil),
|
||||
Certificates: certs,
|
||||
|
|
46
blocknotify-dcr/glide.lock
generated
Normal file
46
blocknotify-dcr/glide.lock
generated
Normal file
|
@ -0,0 +1,46 @@
|
|||
hash: 4e74a8534cece2f2c1de27bcab0da6efba0e47d533cf8475f588e87851473e81
|
||||
updated: 2017-09-12T12:14:36.151798958+02:00
|
||||
imports:
|
||||
- name: github.com/btcsuite/btclog
|
||||
version: 73889fb79bd687870312b6e40effcecffbd57d30
|
||||
- name: github.com/btcsuite/go-socks
|
||||
version: 4720035b7bfd2a9bb130b1c184f8bbe41b6f0d0f
|
||||
subpackages:
|
||||
- socks
|
||||
- name: github.com/btcsuite/seelog
|
||||
version: 313961b101eb55f65ae0f03ddd4e322731763b6c
|
||||
- name: github.com/btcsuite/websocket
|
||||
version: 31079b6807923eb23992c421b114992b95131b55
|
||||
- name: github.com/decred/blake256
|
||||
version: a840e32d7c31fe2e0218607334cb120a683951a4
|
||||
- name: github.com/decred/dcrd
|
||||
version: 5bed758f85159b2ee76240207ba775c40000a4c1
|
||||
subpackages:
|
||||
- blockchain/stake
|
||||
- blockchain/stake/internal/dbnamespace
|
||||
- blockchain/stake/internal/ticketdb
|
||||
- blockchain/stake/internal/tickettreap
|
||||
- chaincfg
|
||||
- chaincfg/chainec
|
||||
- chaincfg/chainhash
|
||||
- database
|
||||
- dcrec/edwards
|
||||
- dcrec/secp256k1
|
||||
- dcrec/secp256k1/schnorr
|
||||
- dcrjson
|
||||
- txscript
|
||||
- wire
|
||||
- name: github.com/decred/dcrrpcclient
|
||||
version: d6edcb0f8f2d01fbf9169f240f73756b41423189
|
||||
- name: github.com/decred/dcrutil
|
||||
version: ebd2e98736e819ac043d54439969b30144b92ced
|
||||
subpackages:
|
||||
- base58
|
||||
- name: github.com/decred/ed25519
|
||||
version: b0909d3f798b97a03c9e77023f97a5301a2a7900
|
||||
subpackages:
|
||||
- edwards25519
|
||||
- name: golang.org/x/crypto
|
||||
version: c7af5bf2638a1164f2eb5467c39c6cffbd13a02e
|
||||
subpackages:
|
||||
- ripemd160
|
9
blocknotify-dcr/glide.yaml
Normal file
9
blocknotify-dcr/glide.yaml
Normal file
|
@ -0,0 +1,9 @@
|
|||
package: github.com/tpruvot/yiimp/blocknotify-dcr
|
||||
import:
|
||||
- package: github.com/decred/dcrd
|
||||
subpackages:
|
||||
- wire
|
||||
- package: github.com/decred/dcrjson
|
||||
# - package: github.com/decred/dcrrpcclient
|
||||
- package: github.com/decred/dcrutil
|
||||
|
859
install.sh
Normal file
859
install.sh
Normal file
|
@ -0,0 +1,859 @@
|
|||
#!/bin/bash
|
||||
################################################################################
|
||||
# Original Author: Oakey22
|
||||
# Maintained by: Coolguy3289
|
||||
# Version 1.99 (April 2021)
|
||||
#
|
||||
# Program:
|
||||
# Install Lbry Pool on Ubuntu 18.04 running Nginx, MariaDB, and php7.x
|
||||
#
|
||||
################################################################################
|
||||
output() {
|
||||
printf "\E[0;33;40m"
|
||||
echo $1
|
||||
printf "\E[0m"
|
||||
}
|
||||
|
||||
displayErr() {
|
||||
echo
|
||||
echo $1;
|
||||
echo
|
||||
exit 1;
|
||||
}
|
||||
clear
|
||||
output "Make sure you double check before hitting enter! Only one shot at these!"
|
||||
output ""
|
||||
read -e -p "Enter time zone (e.g. America/New_York) : " TIME
|
||||
read -e -p "Server name (no http:// or www. just example.com) : " server_name
|
||||
read -e -p "Are you using a subdomain (pool.example.com?) [y/N] : " sub_domain
|
||||
read -e -p "Enter support email (e.g. admin@example.com) : " EMAIL
|
||||
read -e -p "Set stratum to AutoExchange? i.e. mine any coin with BTC address? [y/N] : " BTC
|
||||
read -e -p "Please enter a new location for /site/adminRights this is to customize the admin entrance url (e.g. myAdminpanel) : " admin_panel
|
||||
read -e -p "Enter your Public IP for admin access (http://www.whatsmyip.org/) : " Public
|
||||
read -e -p "Install Fail2ban? [Y/n] : " install_fail2ban
|
||||
read -e -p "Install UFW and configure ports? [Y/n] : " UFW
|
||||
read -e -p "Install LetsEncrypt SSL? IMPORTANT! You MUST have your domain name pointed to this server prior to running the script!! [Y/n]: " ssl_install
|
||||
|
||||
clear
|
||||
output "If you found this helpful, please donate to BTC Donation: "
|
||||
output ""
|
||||
output "Updating system and installing required packages."
|
||||
output ""
|
||||
|
||||
# update package and upgrade Ubuntu
|
||||
output "Updating System through apt"
|
||||
sudo apt update
|
||||
sudo apt upgrade -y
|
||||
sudo apt autoremove -y
|
||||
output "Removing Snapd, and Cloud-Init (Ubuntu 18.x+)
|
||||
sudo snap stop lxc && sudo snap remove lxc
|
||||
sudo snap stop core18 && sudo snap remove core18
|
||||
sudo snap remove snapd
|
||||
sudo apt purge -y snapd*
|
||||
sudo apt purge cloud-init*
|
||||
sudo rm -rf /etc/cloud
|
||||
sudo apt autoremove -y
|
||||
clear
|
||||
# install all dependencies
|
||||
output "Installing MySQL Repository."
|
||||
output ""
|
||||
wget https://dev.mysql.com/get/mysql-apt-config_0.8.14-1_all.deb
|
||||
sudo dpkg -i ./mysql-apt-config_0.8.14-1_all.deb
|
||||
sudo apt update
|
||||
# create random password
|
||||
rootpasswd=$(openssl rand -base64 12)
|
||||
export DEBIAN_FRONTEND="noninteractive"
|
||||
output "Installing pre-requisite repos."
|
||||
output ""
|
||||
sudo apt install software-properties-common -y
|
||||
sudo add-apt-repository ppa:ondrej/php -y
|
||||
sudo add-apt-repository ppa:bitcoin/bitcoin -y
|
||||
sudo apt update
|
||||
output "Installing Required Software."
|
||||
output ""
|
||||
sudo apt install nginx mysql-server php7.4-opcache php7.4-fpm php7.4-common php7.4-gd php7.4-mysql php7.4-imap php7.4-cli php7.4-cgi php7.4-curl php7.4-intl php7.4-pspell recode php7.4-sqlite3 php7.4-tidy php7.4-xmlrpc php7.4-xsl php7.4-memcache php7.4-imagick php7.4-zip php7.4-mbstring php-pear php-auth-sasl mcrypt imagemagick libruby memcached libgmp3-dev libmysqlclient-dev libcurl4-gnutls-dev libkrb5-dev libldap2-dev libidn11-dev gnutls-dev librtmp-dev build-essential libtool autotools-dev automake pkg-config libssl-dev libevent-dev bsdmainutils sendmail git pwgen unzip libdb4.8-dev libdb4.8++-dev libssl-dev libboost-all-dev libminiupnpc-dev libqt5gui5 libqt5core5a libqt5webkit5-dev libqt5dbus5 qttools5-dev qttools5-dev-tools libprotobuf-dev protobuf-compiler libqrencode-dev libnghttp2-dev libpsl-dev -y
|
||||
output "Configuring Nginx server."
|
||||
output ""
|
||||
sudo rm /etc/nginx/sites-enabled/default
|
||||
sudo service nginx start
|
||||
sudo service cron start
|
||||
#Making Nginx a bit hard
|
||||
echo 'map $http_user_agent $blockedagent {
|
||||
default 0;
|
||||
~*malicious 1;
|
||||
~*bot 1;
|
||||
~*backdoor 1;
|
||||
~*crawler 1;
|
||||
~*bandit 1;
|
||||
}
|
||||
' | sudo -E tee /etc/nginx/blockuseragents.rules >/dev/null 2>&1
|
||||
|
||||
#Generating Random Passwords
|
||||
password=`cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1`
|
||||
password2=`cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1`
|
||||
AUTOGENERATED_PASS=`pwgen -c -1 20`
|
||||
output "Testing to see if server emails are sent"
|
||||
output ""
|
||||
if [[ "$root_email" != "" ]]; then
|
||||
echo $root_email > sudo tee --append ~/.email
|
||||
echo $root_email > sudo tee --append ~/.forward
|
||||
|
||||
if [[ ("$send_email" == "y" || "$send_email" == "Y" || "$send_email" == "") ]]; then
|
||||
echo "This is a mail test for the SMTP Service." > sudo tee --append /tmp/email.message
|
||||
echo "You should receive this !" >> sudo tee --append /tmp/email.message
|
||||
echo "" >> sudo tee --append /tmp/email.message
|
||||
echo "Cheers" >> sudo tee --append /tmp/email.message
|
||||
sudo sendmail -s "SMTP Testing" $root_email < sudo tee --append /tmp/email.message
|
||||
|
||||
sudo rm -f /tmp/email.message
|
||||
echo "Mail sent"
|
||||
fi
|
||||
fi
|
||||
|
||||
output "Some optional installs"
|
||||
if [[ ("$install_fail2ban" == "y" || "$install_fail2ban" == "Y" || "$install_fail2ban" == "") ]]; then
|
||||
sudo apt install fail2ban -y
|
||||
fi
|
||||
if [[ ("$UFW" == "y" || "$UFW" == "Y" || "$UFW" == "") ]]; then
|
||||
sudo apt-get install ufw -y
|
||||
sudo ufw default deny incoming
|
||||
sudo ufw default allow outgoing
|
||||
sudo ufw allow ssh
|
||||
sudo ufw allow http
|
||||
sudo ufw allow https
|
||||
sudo ufw allow 3334/tcp
|
||||
sudo ufw --force enable
|
||||
fi
|
||||
|
||||
clear
|
||||
|
||||
output " Installing yiimp"
|
||||
output ""
|
||||
output "Grabbing yiimp fron Github, building files and setting file structure."
|
||||
output ""
|
||||
#Generating Random Password for stratum
|
||||
blckntifypass=`cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1`
|
||||
cd ~
|
||||
git clone https://github.com/lbryio/pool.git yiimp
|
||||
cd $HOME/yiimp/blocknotify
|
||||
sudo sed -i 's/tu8tu5/'$blckntifypass'/' blocknotify.cpp
|
||||
sudo make
|
||||
cd $HOME/yiimp/stratum/iniparser
|
||||
sudo make
|
||||
cd $HOME/yiimp/stratum
|
||||
if [[ ("$BTC" == "y" || "$BTC" == "Y") ]]; then
|
||||
sudo sed -i 's/CFLAGS += -DNO_EXCHANGE/#CFLAGS += -DNO_EXCHANGE/' $HOME/yiimp/stratum/Makefile
|
||||
sudo make
|
||||
fi
|
||||
sudo make
|
||||
cd $HOME/yiimp
|
||||
sudo sed -i 's/AdminRights/'$admin_panel'/' $HOME/yiimp/web/yaamp/modules/site/SiteController.php
|
||||
sudo cp -r $HOME/yiimp/web /var/
|
||||
sudo mkdir -p /var/stratum
|
||||
cd $HOME/yiimp/stratum
|
||||
sudo cp -a config.sample/. /var/stratum/config
|
||||
sudo cp -r stratum /var/stratum
|
||||
sudo cp -r run.sh /var/stratum
|
||||
cd $HOME/yiimp
|
||||
sudo cp -r $HOME/yiimp/bin/. /bin/
|
||||
# sudo cp -r $HOME/yiimp/blocknotify/blocknotify /var/stratum
|
||||
sudo cp -r $HOME/yiimp/blocknotify/blocknotify /usr/bin
|
||||
sudo mkdir -p /etc/yiimp
|
||||
sudo mkdir -p /$HOME/backup/
|
||||
#fixing yiimp
|
||||
sed -i "s|ROOTDIR=/data/yiimp|ROOTDIR=/var|g" /bin/yiimp
|
||||
#fixing run.sh
|
||||
sudo rm -r /var/stratum/config/run.sh
|
||||
echo '
|
||||
#!/bin/bash
|
||||
ulimit -n 10240
|
||||
ulimit -u 10240
|
||||
cd /var/stratum
|
||||
while true; do
|
||||
./stratum /var/stratum/config/$1
|
||||
sleep 2
|
||||
done
|
||||
exec bash
|
||||
' | sudo -E tee /var/stratum/config/run.sh >/dev/null 2>&1
|
||||
sudo chmod +x /var/stratum/config/run.sh
|
||||
output "Update default timezone."
|
||||
output "Thanks for using this installation script. Donations welcome"
|
||||
# check if link file
|
||||
sudo [ -L /etc/localtime ] && sudo unlink /etc/localtime
|
||||
# update time zone
|
||||
sudo ln -sf /usr/share/zoneinfo/$TIME /etc/localtime
|
||||
sudo apt install -y ntpdate
|
||||
# write time to clock.
|
||||
sudo hwclock -w
|
||||
clear
|
||||
output "Making Web Server Magic Happen!"
|
||||
# adding user to group, creating dir structure, setting permissions
|
||||
sudo mkdir -p /var/www/$server_name/html
|
||||
output "Creating webserver initial config file"
|
||||
output ""
|
||||
if [[ ("$sub_domain" == "y" || "$sub_domain" == "Y") ]]; then
|
||||
echo 'include /etc/nginx/blockuseragents.rules;
|
||||
server {
|
||||
if ($blockedagent) {
|
||||
return 403;
|
||||
}
|
||||
if ($request_method !~ ^(GET|HEAD|POST)$) {
|
||||
return 444;
|
||||
}
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
server_name '"${server_name}"';
|
||||
root "/var/www/'"${server_name}"'/html/web";
|
||||
index index.html index.htm index.php;
|
||||
charset utf-8;
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ /index.php?$args;
|
||||
}
|
||||
location @rewrite {
|
||||
rewrite ^/(.*)$ /index.php?r=$1;
|
||||
}
|
||||
|
||||
location = /favicon.ico { access_log off; log_not_found off; }
|
||||
location = /robots.txt { access_log off; log_not_found off; }
|
||||
|
||||
access_log off;
|
||||
error_log /var/log/nginx/'"${server_name}"'.app-error.log error;
|
||||
|
||||
# allow larger file uploads and longer script runtimes
|
||||
client_body_buffer_size 50k;
|
||||
client_header_buffer_size 50k;
|
||||
client_max_body_size 50k;
|
||||
large_client_header_buffers 2 50k;
|
||||
sendfile off;
|
||||
|
||||
location ~ ^/index\.php$ {
|
||||
fastcgi_split_path_info ^(.+\.php)(/.+)$;
|
||||
fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
|
||||
fastcgi_index index.php;
|
||||
include fastcgi_params;
|
||||
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||
fastcgi_intercept_errors off;
|
||||
fastcgi_buffer_size 16k;
|
||||
fastcgi_buffers 4 16k;
|
||||
fastcgi_connect_timeout 300;
|
||||
fastcgi_send_timeout 300;
|
||||
fastcgi_read_timeout 300;
|
||||
try_files $uri $uri/ =404;
|
||||
}
|
||||
location ~ \.php$ {
|
||||
return 404;
|
||||
}
|
||||
location ~ \.sh {
|
||||
return 404;
|
||||
}
|
||||
location ~ /\.ht {
|
||||
deny all;
|
||||
}
|
||||
location ~ /.well-known {
|
||||
allow all;
|
||||
}
|
||||
location /phpmyadmin {
|
||||
root /usr/share/;
|
||||
index index.php;
|
||||
try_files $uri $uri/ =404;
|
||||
location ~ ^/phpmyadmin/(doc|sql|setup)/ {
|
||||
deny all;
|
||||
}
|
||||
location ~ /phpmyadmin/(.+\.php)$ {
|
||||
fastcgi_pass unix:/run/php/php7.4-fpm.sock;
|
||||
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||
include fastcgi_params;
|
||||
include snippets/fastcgi-php.conf;
|
||||
}
|
||||
}
|
||||
}
|
||||
' | sudo -E tee /etc/nginx/sites-available/$server_name.conf >/dev/null 2>&1
|
||||
|
||||
sudo ln -s /etc/nginx/sites-available/$server_name.conf /etc/nginx/sites-enabled/$server_name.conf
|
||||
sudo ln -s /var/web /var/www/$server_name/html
|
||||
sudo service nginx restart
|
||||
if [[ ("$ssl_install" == "y" || "$ssl_install" == "Y" || "$ssl_install" == "") ]]; then
|
||||
output "Install LetsEncrypt and setting SSL"
|
||||
sudo apt install software-properties-common
|
||||
sudo add-apt-repository universe
|
||||
sudo add-apt-repository ppa:certbot/certbot
|
||||
sudo apt update
|
||||
sudo apt install -y certbot python-certbot-nginx
|
||||
sudo certbot certonly -a webroot --webroot-path=/var/web --email "$EMAIL" --agree-tos -d "$server_name"
|
||||
sudo rm /etc/nginx/sites-available/$server_name.conf
|
||||
sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048
|
||||
# I am SSL Man!
|
||||
echo 'include /etc/nginx/blockuseragents.rules;
|
||||
server {
|
||||
if ($blockedagent) {
|
||||
return 403;
|
||||
}
|
||||
if ($request_method !~ ^(GET|HEAD|POST)$) {
|
||||
return 444;
|
||||
}
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
server_name '"${server_name}"';
|
||||
# enforce https
|
||||
return 301 https://$server_name$request_uri;
|
||||
}
|
||||
|
||||
server {
|
||||
if ($blockedagent) {
|
||||
return 403;
|
||||
}
|
||||
if ($request_method !~ ^(GET|HEAD|POST)$) {
|
||||
return 444;
|
||||
}
|
||||
listen 443 ssl http2;
|
||||
listen [::]:443 ssl http2;
|
||||
server_name '"${server_name}"';
|
||||
|
||||
root /var/www/'"${server_name}"'/html/web;
|
||||
index index.php;
|
||||
|
||||
access_log /var/log/nginx/'"${server_name}"'.app-accress.log;
|
||||
error_log /var/log/nginx/'"${server_name}"'.app-error.log error;
|
||||
|
||||
# allow larger file uploads and longer script runtimes
|
||||
client_body_buffer_size 50k;
|
||||
client_header_buffer_size 50k;
|
||||
client_max_body_size 50k;
|
||||
large_client_header_buffers 2 50k;
|
||||
sendfile off;
|
||||
|
||||
# strengthen ssl security
|
||||
ssl_certificate /etc/letsencrypt/live/'"${server_name}"'/fullchain.pem;
|
||||
ssl_certificate_key /etc/letsencrypt/live/'"${server_name}"'/privkey.pem;
|
||||
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
|
||||
ssl_prefer_server_ciphers on;
|
||||
ssl_session_cache shared:SSL:10m;
|
||||
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:ECDHE-RSA-AES128-GCM-SHA256:AES256+EECDH:DHE-RSA-AES128-GCM-SHA256:AES256+EDH:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4";
|
||||
ssl_dhparam /etc/ssl/certs/dhparam.pem;
|
||||
|
||||
# Add headers to serve security related headers
|
||||
add_header Strict-Transport-Security "max-age=15768000; preload;";
|
||||
add_header X-Content-Type-Options nosniff;
|
||||
add_header X-XSS-Protection "1; mode=block";
|
||||
add_header X-Robots-Tag none;
|
||||
add_header Content-Security-Policy "frame-ancestors 'self'";
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ /index.php?$args;
|
||||
}
|
||||
location @rewrite {
|
||||
rewrite ^/(.*)$ /index.php?r=$1;
|
||||
}
|
||||
|
||||
|
||||
location ~ ^/index\.php$ {
|
||||
fastcgi_split_path_info ^(.+\.php)(/.+)$;
|
||||
fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
|
||||
fastcgi_index index.php;
|
||||
include fastcgi_params;
|
||||
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||
fastcgi_intercept_errors off;
|
||||
fastcgi_buffer_size 16k;
|
||||
fastcgi_buffers 4 16k;
|
||||
fastcgi_connect_timeout 300;
|
||||
fastcgi_send_timeout 300;
|
||||
fastcgi_read_timeout 300;
|
||||
include /etc/nginx/fastcgi_params;
|
||||
try_files $uri $uri/ =404;
|
||||
}
|
||||
location ~ \.php$ {
|
||||
return 404;
|
||||
}
|
||||
location ~ \.sh {
|
||||
return 404;
|
||||
}
|
||||
|
||||
location ~ /\.ht {
|
||||
deny all;
|
||||
}
|
||||
location /phpmyadmin {
|
||||
root /usr/share/;
|
||||
index index.php;
|
||||
try_files $uri $uri/ =404;
|
||||
location ~ ^/phpmyadmin/(doc|sql|setup)/ {
|
||||
deny all;
|
||||
}
|
||||
location ~ /phpmyadmin/(.+\.php)$ {
|
||||
fastcgi_pass unix:/run/php/php7.4-fpm.sock;
|
||||
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||
include fastcgi_params;
|
||||
include snippets/fastcgi-php.conf;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
' | sudo -E tee /etc/nginx/sites-available/$server_name.conf >/dev/null 2>&1
|
||||
fi
|
||||
sudo service nginx restart
|
||||
sudo service php7.4-fpm reload
|
||||
else
|
||||
echo 'include /etc/nginx/blockuseragents.rules;
|
||||
server {
|
||||
if ($blockedagent) {
|
||||
return 403;
|
||||
}
|
||||
if ($request_method !~ ^(GET|HEAD|POST)$) {
|
||||
return 444;
|
||||
}
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
server_name '"${server_name}"' www.'"${server_name}"';
|
||||
root "/var/www/'"${server_name}"'/html/web";
|
||||
index index.html index.htm index.php;
|
||||
charset utf-8;
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ /index.php?$args;
|
||||
}
|
||||
location @rewrite {
|
||||
rewrite ^/(.*)$ /index.php?r=$1;
|
||||
}
|
||||
|
||||
location = /favicon.ico { access_log off; log_not_found off; }
|
||||
location = /robots.txt { access_log off; log_not_found off; }
|
||||
|
||||
access_log off;
|
||||
error_log /var/log/nginx/'"${server_name}"'.app-error.log error;
|
||||
|
||||
# allow larger file uploads and longer script runtimes
|
||||
client_body_buffer_size 50k;
|
||||
client_header_buffer_size 50k;
|
||||
client_max_body_size 50k;
|
||||
large_client_header_buffers 2 50k;
|
||||
sendfile off;
|
||||
|
||||
location ~ ^/index\.php$ {
|
||||
fastcgi_split_path_info ^(.+\.php)(/.+)$;
|
||||
fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
|
||||
fastcgi_index index.php;
|
||||
include fastcgi_params;
|
||||
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||
fastcgi_intercept_errors off;
|
||||
fastcgi_buffer_size 16k;
|
||||
fastcgi_buffers 4 16k;
|
||||
fastcgi_connect_timeout 300;
|
||||
fastcgi_send_timeout 300;
|
||||
fastcgi_read_timeout 300;
|
||||
try_files $uri $uri/ =404;
|
||||
}
|
||||
location ~ \.php$ {
|
||||
return 404;
|
||||
}
|
||||
location ~ \.sh {
|
||||
return 404;
|
||||
}
|
||||
location ~ /\.ht {
|
||||
deny all;
|
||||
}
|
||||
location ~ /.well-known {
|
||||
allow all;
|
||||
}
|
||||
location /phpmyadmin {
|
||||
root /usr/share/;
|
||||
index index.php;
|
||||
try_files $uri $uri/ =404;
|
||||
location ~ ^/phpmyadmin/(doc|sql|setup)/ {
|
||||
deny all;
|
||||
}
|
||||
location ~ /phpmyadmin/(.+\.php)$ {
|
||||
fastcgi_pass unix:/run/php/php7.4-fpm.sock;
|
||||
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||
include fastcgi_params;
|
||||
include snippets/fastcgi-php.conf;
|
||||
}
|
||||
}
|
||||
}
|
||||
' | sudo -E tee /etc/nginx/sites-available/$server_name.conf >/dev/null 2>&1
|
||||
|
||||
sudo ln -s /etc/nginx/sites-available/$server_name.conf /etc/nginx/sites-enabled/$server_name.conf
|
||||
sudo ln -s /var/web /var/www/$server_name/html
|
||||
sudo service nginx restart
|
||||
if [[ ("$ssl_install" == "y" || "$ssl_install" == "Y" || "$ssl_install" == "") ]]; then
|
||||
output "Install LetsEncrypt and setting SSL"
|
||||
sudo apt install software-properties-common
|
||||
sudo add-apt-repository universe
|
||||
sudo add-apt-repository ppa:certbot/certbot
|
||||
sudo apt update
|
||||
sudo apt install -y certbot python-certbot-nginx
|
||||
sudo certbot certonly -a webroot --webroot-path=/var/web --email "$EMAIL" --agree-tos -d "$server_name" -d www."$server_name"
|
||||
sudo rm /etc/nginx/sites-available/$server_name.conf
|
||||
sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048
|
||||
# I am SSL Man!
|
||||
echo 'include /etc/nginx/blockuseragents.rules;
|
||||
server {
|
||||
if ($blockedagent) {
|
||||
return 403;
|
||||
}
|
||||
if ($request_method !~ ^(GET|HEAD|POST)$) {
|
||||
return 444;
|
||||
}
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
server_name '"${server_name}"';
|
||||
# enforce https
|
||||
return 301 https://$server_name$request_uri;
|
||||
}
|
||||
|
||||
server {
|
||||
if ($blockedagent) {
|
||||
return 403;
|
||||
}
|
||||
if ($request_method !~ ^(GET|HEAD|POST)$) {
|
||||
return 444;
|
||||
}
|
||||
listen 443 ssl http2;
|
||||
listen [::]:443 ssl http2;
|
||||
server_name '"${server_name}"' www.'"${server_name}"';
|
||||
|
||||
root /var/www/'"${server_name}"'/html/web;
|
||||
index index.php;
|
||||
|
||||
access_log /var/log/nginx/'"${server_name}"'.app-accress.log;
|
||||
error_log /var/log/nginx/'"${server_name}"'.app-error.log error;
|
||||
|
||||
# allow larger file uploads and longer script runtimes
|
||||
client_body_buffer_size 50k;
|
||||
client_header_buffer_size 50k;
|
||||
client_max_body_size 50k;
|
||||
large_client_header_buffers 2 50k;
|
||||
sendfile off;
|
||||
|
||||
# strengthen ssl security
|
||||
ssl_certificate /etc/letsencrypt/live/'"${server_name}"'/fullchain.pem;
|
||||
ssl_certificate_key /etc/letsencrypt/live/'"${server_name}"'/privkey.pem;
|
||||
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
|
||||
ssl_prefer_server_ciphers on;
|
||||
ssl_session_cache shared:SSL:10m;
|
||||
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:ECDHE-RSA-AES128-GCM-SHA256:AES256+EECDH:DHE-RSA-AES128-GCM-SHA256:AES256+EDH:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4";
|
||||
ssl_dhparam /etc/ssl/certs/dhparam.pem;
|
||||
|
||||
# Add headers to serve security related headers
|
||||
add_header Strict-Transport-Security "max-age=15768000; preload;";
|
||||
add_header X-Content-Type-Options nosniff;
|
||||
add_header X-XSS-Protection "1; mode=block";
|
||||
add_header X-Robots-Tag none;
|
||||
add_header Content-Security-Policy "frame-ancestors 'self'";
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ /index.php?$args;
|
||||
}
|
||||
location @rewrite {
|
||||
rewrite ^/(.*)$ /index.php?r=$1;
|
||||
}
|
||||
|
||||
|
||||
location ~ ^/index\.php$ {
|
||||
fastcgi_split_path_info ^(.+\.php)(/.+)$;
|
||||
fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
|
||||
fastcgi_index index.php;
|
||||
include fastcgi_params;
|
||||
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||
fastcgi_intercept_errors off;
|
||||
fastcgi_buffer_size 16k;
|
||||
fastcgi_buffers 4 16k;
|
||||
fastcgi_connect_timeout 300;
|
||||
fastcgi_send_timeout 300;
|
||||
fastcgi_read_timeout 300;
|
||||
include /etc/nginx/fastcgi_params;
|
||||
try_files $uri $uri/ =404;
|
||||
}
|
||||
location ~ \.php$ {
|
||||
return 404;
|
||||
}
|
||||
location ~ \.sh {
|
||||
return 404;
|
||||
}
|
||||
|
||||
location ~ /\.ht {
|
||||
deny all;
|
||||
}
|
||||
location /phpmyadmin {
|
||||
root /usr/share/;
|
||||
index index.php;
|
||||
try_files $uri $uri/ =404;
|
||||
location ~ ^/phpmyadmin/(doc|sql|setup)/ {
|
||||
deny all;
|
||||
}
|
||||
location ~ /phpmyadmin/(.+\.php)$ {
|
||||
fastcgi_pass unix:/run/php/php7.4-fpm.sock;
|
||||
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||
include fastcgi_params;
|
||||
include snippets/fastcgi-php.conf;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
' | sudo -E tee /etc/nginx/sites-available/$server_name.conf >/dev/null 2>&1
|
||||
fi
|
||||
sudo service nginx restart
|
||||
sudo service php7.4-fpm reload
|
||||
fi
|
||||
clear
|
||||
output "Now for the database fun!"
|
||||
# create database
|
||||
Q1="CREATE DATABASE IF NOT EXISTS yiimpfrontend;"
|
||||
Q2="GRANT ALL ON *.* TO 'panel'@'localhost' IDENTIFIED BY '$password';"
|
||||
Q3="FLUSH PRIVILEGES;"
|
||||
SQL="${Q1}${Q2}${Q3}"
|
||||
sudo mysql -u root -p="" -e "$SQL"
|
||||
# create stratum user
|
||||
Q1="GRANT ALL ON *.* TO 'stratum'@'localhost' IDENTIFIED BY '$password2';"
|
||||
Q2="FLUSH PRIVILEGES;"
|
||||
SQL="${Q1}${Q2}"
|
||||
sudo mysql -u root -p="" -e "$SQL"
|
||||
|
||||
#Create my.cnf
|
||||
|
||||
echo '
|
||||
[clienthost1]
|
||||
user=panel
|
||||
password='"${password}"'
|
||||
database=yiimpfrontend
|
||||
host=localhost
|
||||
[clienthost2]
|
||||
user=stratum
|
||||
password='"${password2}"'
|
||||
database=yiimpfrontend
|
||||
host=localhost
|
||||
[mysql]
|
||||
user=root
|
||||
password='"${rootpasswd}"'
|
||||
[myphpadmin]
|
||||
user=root
|
||||
password='"${AUTOGENERATED_PASS}"'
|
||||
' | sudo -E tee ~/.my.cnf >/dev/null 2>&1
|
||||
sudo chmod 0600 ~/.my.cnf
|
||||
|
||||
|
||||
|
||||
#Create keys file
|
||||
echo '
|
||||
<?php
|
||||
/* Sample config file to put in /etc/yiimp/keys.php */
|
||||
define('"'"'YIIMP_MYSQLDUMP_USER'"'"', '"'"'panel'"'"');
|
||||
define('"'"'YIIMP_MYSQLDUMP_PASS'"'"', '"'"''"${password}"''"'"');
|
||||
/* Keys required to create/cancel orders and access your balances/deposit addresses */
|
||||
define('"'"'EXCH_BITTREX_SECRET'"'"', '"'"'<my_bittrex_api_secret_key>'"'"');
|
||||
define('"'"'EXCH_BITSTAMP_SECRET'"'"','"'"''"'"');
|
||||
define('"'"'EXCH_BLEUTRADE_SECRET'"'"', '"'"''"'"');
|
||||
define('"'"'EXCH_BTER_SECRET'"'"', '"'"''"'"');
|
||||
define('"'"'EXCH_CCEX_SECRET'"'"', '"'"''"'"');
|
||||
define('"'"'EXCH_COINMARKETS_PASS'"'"', '"'"''"'"');
|
||||
define('"'"'EXCH_CRYPTOPIA_SECRET'"'"', '"'"''"'"');
|
||||
define('"'"'EXCH_EMPOEX_SECKEY'"'"', '"'"''"'"');
|
||||
define('"'"'EXCH_HITBTC_SECRET'"'"', '"'"''"'"');
|
||||
define('"'"'EXCH_KRAKEN_SECRET'"'"','"'"''"'"');
|
||||
define('"'"'EXCH_LIVECOIN_SECRET'"'"', '"'"''"'"');
|
||||
define('"'"'EXCH_NOVA_SECRET'"'"','"'"''"'"');
|
||||
define('"'"'EXCH_POLONIEX_SECRET'"'"', '"'"''"'"');
|
||||
define('"'"'EXCH_YOBIT_SECRET'"'"', '"'"''"'"');
|
||||
' | sudo -E tee /etc/yiimp/keys.php >/dev/null 2>&1
|
||||
|
||||
output "Peforming the SQL import"
|
||||
output ""
|
||||
cd ~
|
||||
cd yiimp/sql
|
||||
# import sql dump
|
||||
sudo zcat 2016-04-03-yaamp.sql.gz | sudo mysql --defaults-group-suffix=host1
|
||||
# oh the humanity!
|
||||
sudo mysql --defaults-group-suffix=host1 --force < 2016-04-24-market_history.sql
|
||||
sudo mysql --defaults-group-suffix=host1 --force < 2016-04-27-settings.sql
|
||||
sudo mysql --defaults-group-suffix=host1 --force < 2016-05-11-coins.sql
|
||||
sudo mysql --defaults-group-suffix=host1 --force < 2016-05-15-benchmarks.sql
|
||||
sudo mysql --defaults-group-suffix=host1 --force < 2016-05-23-bookmarks.sql
|
||||
sudo mysql --defaults-group-suffix=host1 --force < 2016-06-01-notifications.sql
|
||||
sudo mysql --defaults-group-suffix=host1 --force < 2016-06-04-bench_chips.sql
|
||||
sudo mysql --defaults-group-suffix=host1 --force < 2016-11-23-coins.sql
|
||||
sudo mysql --defaults-group-suffix=host1 --force < 2017-02-05-benchmarks.sql
|
||||
sudo mysql --defaults-group-suffix=host1 --force < 2017-03-31-earnings_index.sql
|
||||
sudo mysql --defaults-group-suffix=host1 --force < 2017-05-accounts_case_swaptime.sql
|
||||
sudo mysql --defaults-group-suffix=host1 --force < 2017-06-payouts_coinid_memo.sql
|
||||
sudo mysql --defaults-group-suffix=host1 --force < 2017-09-notifications.sql
|
||||
sudo mysql --defaults-group-suffix=host1 --force < 2017-11-segwit.sql
|
||||
sudo mysql --defaults-group-suffix=host1 --force < 2018-01-stratums_ports.sql
|
||||
sudo mysql --defaults-group-suffix=host1 --force < 2018-02-coins_getinfo.sql
|
||||
clear
|
||||
output "Generating a basic serverconfig.php"
|
||||
output ""
|
||||
# make config file
|
||||
echo '
|
||||
<?php
|
||||
ini_set('"'"'date.timezone'"'"', '"'"'UTC'"'"');
|
||||
define('"'"'YAAMP_LOGS'"'"', '"'"'/var/log'"'"');
|
||||
define('"'"'YAAMP_HTDOCS'"'"', '"'"'/var/web'"'"');
|
||||
define('"'"'YAAMP_BIN'"'"', '"'"'/var/bin'"'"');
|
||||
define('"'"'YAAMP_DBHOST'"'"', '"'"'localhost'"'"');
|
||||
define('"'"'YAAMP_DBNAME'"'"', '"'"'yiimpfrontend'"'"');
|
||||
define('"'"'YAAMP_DBUSER'"'"', '"'"'panel'"'"');
|
||||
define('"'"'YAAMP_DBPASSWORD'"'"', '"'"''"${password}"''"'"');
|
||||
define('"'"'YAAMP_PRODUCTION'"'"', true);
|
||||
define('"'"'YAAMP_RENTAL'"'"', false);
|
||||
define('"'"'YAAMP_LIMIT_ESTIMATE'"'"', false);
|
||||
define('"'"'YAAMP_FEES_MINING'"'"', 0.5);
|
||||
define('"'"'YAAMP_FEES_EXCHANGE'"'"', 2);
|
||||
define('"'"'YAAMP_FEES_RENTING'"'"', 2);
|
||||
define('"'"'YAAMP_TXFEE_RENTING_WD'"'"', 0.002);
|
||||
define('"'"'YAAMP_PAYMENTS_FREQ'"'"', 3*60*60);
|
||||
define('"'"'YAAMP_PAYMENTS_MINI'"'"', 0.001);
|
||||
define('"'"'YAAMP_ALLOW_EXCHANGE'"'"', false);
|
||||
define('"'"'YIIMP_PUBLIC_EXPLORER'"'"', true);
|
||||
define('"'"'YIIMP_PUBLIC_BENCHMARK'"'"', true);
|
||||
define('"'"'YIIMP_FIAT_ALTERNATIVE'"'"', '"'"'USD'"'"'); // USD is main
|
||||
define('"'"'YAAMP_USE_NICEHASH_API'"'"', false);
|
||||
define('"'"'YAAMP_BTCADDRESS'"'"', '"'"'1NMDeanjyad2gcpumbZmF13fMLqDKNxxQ5'"'"');
|
||||
define('"'"'YAAMP_SITE_URL'"'"', '"'"''"${server_name}"''"'"');
|
||||
define('"'"'YAAMP_STRATUM_URL'"'"', YAAMP_SITE_URL); // change if your stratum server is on a different host
|
||||
define('"'"'YAAMP_SITE_NAME'"'"', '"'"'Crypto'"'"');
|
||||
define('"'"'YAAMP_ADMIN_EMAIL'"'"', '"'"''"${EMAIL}"''"'"');
|
||||
define('"'"'YAAMP_ADMIN_IP'"'"', '"'"''"${Public}"''"'"'); // samples: "80.236.118.26,90.234.221.11" or "10.0.0.1/8"
|
||||
define('"'"'YAAMP_ADMIN_WEBCONSOLE'"'"', true);
|
||||
define('"'"'YAAMP_NOTIFY_NEW_COINS'"'"', false);
|
||||
define('"'"'YAAMP_DEFAULT_ALGO'"'"', '"'"'lbry'"'"');
|
||||
define('"'"'YAAMP_USE_NGINX'"'"', true);
|
||||
// Exchange public keys (private keys are in a separate config file)
|
||||
define('"'"'EXCH_CRYPTOPIA_KEY'"'"', '"'"''"'"');
|
||||
define('"'"'EXCH_POLONIEX_KEY'"'"', '"'"''"'"');
|
||||
define('"'"'EXCH_BITTREX_KEY'"'"', '"'"''"'"');
|
||||
define('"'"'EXCH_BLEUTRADE_KEY'"'"', '"'"''"'"');
|
||||
define('"'"'EXCH_BTER_KEY'"'"', '"'"''"'"');
|
||||
define('"'"'EXCH_YOBIT_KEY'"'"', '"'"''"'"');
|
||||
define('"'"'EXCH_CCEX_KEY'"'"', '"'"''"'"');
|
||||
define('"'"'EXCH_COINMARKETS_USER'"'"', '"'"''"'"');
|
||||
define('"'"'EXCH_COINMARKETS_PIN'"'"', '"'"''"'"');
|
||||
define('"'"'EXCH_BITSTAMP_ID'"'"','"'"''"'"');
|
||||
define('"'"'EXCH_BITSTAMP_KEY'"'"','"'"''"'"');
|
||||
define('"'"'EXCH_HITBTC_KEY'"'"','"'"''"'"');
|
||||
define('"'"'EXCH_KRAKEN_KEY'"'"', '"'"''"'"');
|
||||
define('"'"'EXCH_LIVECOIN_KEY'"'"', '"'"''"'"');
|
||||
define('"'"'EXCH_NOVA_KEY'"'"', '"'"''"'"');
|
||||
// Automatic withdraw to Yaamp btc wallet if btc balance > 0.3
|
||||
define('"'"'EXCH_AUTO_WITHDRAW'"'"', 0.3);
|
||||
// nicehash keys deposit account & amount to deposit at a time
|
||||
define('"'"'NICEHASH_API_KEY'"'"','"'"''"'"');
|
||||
define('"'"'NICEHASH_API_ID'"'"','"'"''"'"');
|
||||
define('"'"'NICEHASH_DEPOSIT'"'"','"'"''"'"');
|
||||
define('"'"'NICEHASH_DEPOSIT_AMOUNT'"'"','"'"''"'"');
|
||||
$cold_wallet_table = array(
|
||||
'"'"'1NMDeanjyad2gcpumbZmF13fMLqDKNxxQ5'"'"' => 0.10,
|
||||
);
|
||||
// Sample fixed pool fees
|
||||
$configFixedPoolFees = array(
|
||||
'"'"'zr5'"'"' => 2.0,
|
||||
'"'"'scrypt'"'"' => 20.0,
|
||||
'"'"'sha256'"'"' => 5.0,
|
||||
);
|
||||
// Sample custom stratum ports
|
||||
$configCustomPorts = array(
|
||||
// '"'"'x11'"'"' => 7000,
|
||||
);
|
||||
// mBTC Coefs per algo (default is 1.0)
|
||||
$configAlgoNormCoef = array(
|
||||
// '"'"'x11'"'"' => 5.0,
|
||||
);
|
||||
' | sudo -E tee /var/web/serverconfig.php >/dev/null 2>&1
|
||||
|
||||
output "Adding tmux start file to ~/"
|
||||
echo '
|
||||
#!/bin/bash
|
||||
LOG_DIR=/var/log
|
||||
WEB_DIR=/var/web
|
||||
STRATUM_DIR=/var/stratum
|
||||
USR_BIN=/usr/bin
|
||||
tmux new -d -s main bash $WEB_DIR/main.sh
|
||||
tmux new -d -s loop2 bash $WEB_DIR/loop2.sh
|
||||
tmux new -d -s blocks bash $WEB_DIR/blocks.sh
|
||||
tmux new -d -s debug tail -f $LOG_DIR/debug.log
|
||||
tmux new -d -s stratum bash $STRATUM_DIR/run.sh lbry
|
||||
' | sudo -E tee ~/pool-start.sh >/dev/null 2>&1
|
||||
sudo chmod +x ~/pool-start.sh
|
||||
|
||||
# Old screen commands:
|
||||
# screen -dmS main bash $WEB_DIR/main.sh
|
||||
# screen -dmS loop2 bash $WEB_DIR/loop2.sh
|
||||
# screen -dmS blocks bash $WEB_DIR/blocks.sh
|
||||
# screen -dmS debug tail -f $LOG_DIR/debug.log
|
||||
# screen -dmS stratum bash $STRATUM_DIR/run.sh lbry
|
||||
|
||||
output "Updating stratum config files with database connection info."
|
||||
output ""
|
||||
cd /var/stratum/config
|
||||
sudo sed -i 's/password = tu8tu5/password = '$blckntifypass'/g' *.conf
|
||||
sudo sed -i 's/server = yaamp.com/server = '$server_name'/g' *.conf
|
||||
sudo sed -i 's/host = yaampdb/host = localhost/g' *.conf
|
||||
sudo sed -i 's/database = yaamp/database = yiimpfrontend/g' *.conf
|
||||
sudo sed -i 's/username = root/username = stratum/g' *.conf
|
||||
sudo sed -i 's/password = patofpaq/password = '$password2'/g' *.conf
|
||||
cd ~
|
||||
|
||||
sudo rm -rf $HOME/yiimp
|
||||
sudo service nginx restart
|
||||
sudo service php7.3-fpm reload
|
||||
cd ~
|
||||
wget https://github.com/lbryio/lbrycrd/releases/download/v0.17.3.2/lbrycrd-linux-1732.zip
|
||||
sudo unzip lbrycrd-linux-1732.zip -d /usr/bin
|
||||
|
||||
lbrycrdd -daemon
|
||||
sleep 3
|
||||
lbrycrd-cli stop
|
||||
|
||||
|
||||
# Create config for Lbry
|
||||
echo && echo "Configuring Lbrycrd.conf"
|
||||
sleep 3
|
||||
rpcuser=`cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1`
|
||||
rpcpassword=`cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1`
|
||||
echo '
|
||||
rpcuser='$rpcuser'
|
||||
rpcpassword='$rpcpassword'
|
||||
rpcport=14390
|
||||
rpcthreads=24
|
||||
rpcallowip=127.0.0.1
|
||||
# onlynet=ipv4
|
||||
maxconnections=36
|
||||
daemon=1
|
||||
deprecatedrpc=accounts
|
||||
gen=0
|
||||
alertnotify=echo %s | mail -s "LBRY Credits alert!" ${EMAIL}
|
||||
blocknotify=blocknotify 127.0.0.1:3334 1439 %s
|
||||
' | sudo -E tee ~/.lbrycrd/lbrycrd.conf
|
||||
sleep 3
|
||||
|
||||
|
||||
|
||||
output "Final Directory permissions"
|
||||
output ""
|
||||
whoami=`whoami`
|
||||
sudo usermod -aG www-data $whoami
|
||||
sudo mkdir /root/backup/
|
||||
sudo mkdir /data
|
||||
sudo mkdir /data/yiimp
|
||||
sudo ln -s /var/web /data/yiimp/web
|
||||
sudo chown -R www-data:www-data /var/log
|
||||
sudo chown -R www-data:www-data /var/stratum
|
||||
sudo chown -R www-data:www-data /var/web
|
||||
sudo chmod -R 775 /var/www/$server_name/html
|
||||
sudo chmod -R 775 /var/web
|
||||
sudo chmod -R 775 /var/stratum
|
||||
sudo chmod -R 775 /var/web/yaamp/runtime
|
||||
sudo chmod -R 775 /root/backup/
|
||||
sudo chmod -R 775 /var/log
|
||||
sudo chmod -R 775 /var/web/serverconfig.php
|
||||
sudo chmod a+w /var/web/yaamp/runtime
|
||||
sudo chmod a+w /var/log
|
||||
sudo chmod a+w /var/web/assets
|
||||
|
||||
lbrycrdd -daemon
|
||||
|
||||
clear
|
||||
output "Your mysql information is saved in ~/.my.cnf"
|
||||
output ""
|
||||
output "Please login to the admin panel at http://${server_name}/site/${admin_panel}"
|
||||
output ""
|
||||
output "Your RPC username is ${rpcuser}"
|
||||
output "Your RPC Password is ${rpcpassword}"
|
28
rc.local
28
rc.local
|
@ -17,18 +17,26 @@ screen -dmS loop2 $WEB_DIR/loop2.sh
|
|||
screen -dmS blocks $WEB_DIR/blocks.sh
|
||||
screen -dmS debug tail -f $LOG_DIR/debug.log
|
||||
|
||||
# Stratum ports
|
||||
# Stratum instances (skipped/exit if no .conf)
|
||||
|
||||
screen -dmS c11 $STRATUM_DIR/run.sh c11
|
||||
screen -dmS deep $STRATUM_DIR/run.sh deep
|
||||
|
||||
screen -dmS x11 $STRATUM_DIR/run.sh x11
|
||||
screen -dmS x11evo $STRATUM_DIR/run.sh x11evo
|
||||
screen -dmS x13 $STRATUM_DIR/run.sh x13
|
||||
screen -dmS x14 $STRATUM_DIR/run.sh x14
|
||||
screen -dmS x15 $STRATUM_DIR/run.sh x15
|
||||
#screen -dmS x14 $STRATUM_DIR/run.sh x14
|
||||
#screen -dmS x15 $STRATUM_DIR/run.sh x15
|
||||
#screen -dmS x16r $STRATUM_DIR/run.sh x16r
|
||||
screen -dmS x17 $STRATUM_DIR/run.sh x17
|
||||
screen -dmS xevan $STRATUM_DIR/run.sh xevan
|
||||
screen -dmS timetravel $STRATUM_DIR/run.sh timetravel
|
||||
screen -dmS bitcore $STRATUM_DIR/run.sh bitcore
|
||||
screen -dmS hmq1725 $STRATUM_DIR/run.sh hmq1725
|
||||
screen -dmS tribus $STRATUM_DIR/run.sh tribus
|
||||
|
||||
screen -dmS sha $STRATUM_DIR/run.sh sha
|
||||
screen -dmS sha256t $STRATUM_DIR/run.sh sha256t
|
||||
screen -dmS scrypt $STRATUM_DIR/run.sh scrypt
|
||||
screen -dmS scryptn $STRATUM_DIR/run.sh scryptn
|
||||
screen -dmS luffa $STRATUM_DIR/run.sh luffa
|
||||
|
@ -37,11 +45,16 @@ screen -dmS nist5 $STRATUM_DIR/run.sh nist5
|
|||
screen -dmS penta $STRATUM_DIR/run.sh penta
|
||||
screen -dmS quark $STRATUM_DIR/run.sh quark
|
||||
screen -dmS qubit $STRATUM_DIR/run.sh qubit
|
||||
screen -dmS jha $STRATUM_DIR/run.sh jha
|
||||
#screen -dmS dmd-gr $STRATUM_DIR/run.sh dmd-gr
|
||||
screen -dmS myr-gr $STRATUM_DIR/run.sh myr-gr
|
||||
screen -dmS lbry $STRATUM_DIR/run.sh lbry
|
||||
screen -dmS lyra2 $STRATUM_DIR/run.sh lyra2
|
||||
screen -dmS allium $STRATUM_DIR/run.sh allium
|
||||
#screen -dmS lyra2 $STRATUM_DIR/run.sh lyra2
|
||||
screen -dmS lyra2v2 $STRATUM_DIR/run.sh lyra2v2
|
||||
screen -dmS lyra2z $STRATUM_DIR/run.sh lyra2z
|
||||
screen -dmS lyra2zz $STRATUM_DIR/run.sh lyra2zz
|
||||
screen -dmS rainforest $STRATUM_DIR/run.sh rainforest
|
||||
|
||||
screen -dmS blakecoin $STRATUM_DIR/run.sh blakecoin # blake 8
|
||||
screen -dmS blake $STRATUM_DIR/run.sh blake
|
||||
|
@ -50,15 +63,22 @@ screen -dmS vanilla $STRATUM_DIR/run.sh vanilla # blake 8
|
|||
screen -dmS decred $STRATUM_DIR/run.sh decred # blake 14
|
||||
|
||||
#screen -dmS keccak $STRATUM_DIR/run.sh keccak
|
||||
#screen -dmS keccakc $STRATUM_DIR/run.sh keccakc
|
||||
#screen -dmS phi $STRATUM_DIR/run.sh phi
|
||||
#screen -dmS polytimos $STRATUM_DIR/run.sh polytimos
|
||||
screen -dmS whirlpool $STRATUM_DIR/run.sh whirlpool
|
||||
|
||||
screen -dmS skein $STRATUM_DIR/run.sh skein
|
||||
screen -dmS skein2 $STRATUM_DIR/run.sh skein2
|
||||
screen -dmS yescrypt $STRATUM_DIR/run.sh yescrypt
|
||||
#screen -dmS yescryptR16 $STRATUM_DIR/run.sh yescryptR16
|
||||
screen -dmS zr5 $STRATUM_DIR/run.sh zr5
|
||||
screen -dmS sib $STRATUM_DIR/run.sh sib
|
||||
screen -dmS m7m $STRATUM_DIR/run.sh m7m
|
||||
screen -dmS veltor $STRATUM_DIR/run.sh veltor
|
||||
screen -dmS velvet $STRATUM_DIR/run.sh velvet
|
||||
screen -dmS argon2 $STRATUM_DIR/run.sh argon2
|
||||
screen -dmS argon2d-dyn $STRATUM_DIR/run.sh argon2d-dyn
|
||||
screen -dmS x22i $STRATUM_DIR/run.sh x22i
|
||||
screen -dmS lbk3 $STRATUM_DIR/run.sh lbk3
|
||||
|
||||
|
|
13
sql/2016-11-23-coins.sql
Normal file
13
sql/2016-11-23-coins.sql
Normal file
|
@ -0,0 +1,13 @@
|
|||
-- Recent additions to add after db init (.gz)
|
||||
-- mysql yaamp -p < file.sql
|
||||
|
||||
-- don't forget to restart memcached service to refresh the db structure
|
||||
|
||||
ALTER TABLE `coins` ADD `powend_height` INT(11) NULL AFTER `target_height`;
|
||||
ALTER TABLE `coins` ADD `mature_blocks` INT(11) NULL AFTER `reward_mul`;
|
||||
ALTER TABLE `coins` ADD `block_time` INT(11) NULL AFTER `payout_max`;
|
||||
ALTER TABLE `coins` ADD `available` DOUBLE NULL AFTER `balance`;
|
||||
ALTER TABLE `coins` ADD `cleared` DOUBLE NULL AFTER `balance`;
|
||||
ALTER TABLE `coins` ADD `immature` DOUBLE NULL AFTER `balance`;
|
||||
ALTER TABLE `coins` ADD `max_miners` INT(11) NULL AFTER `visible`;
|
||||
ALTER TABLE `coins` ADD `max_shares` INT(11) NULL AFTER `max_miners`;
|
10
sql/2017-02-05-benchmarks.sql
Normal file
10
sql/2017-02-05-benchmarks.sql
Normal file
|
@ -0,0 +1,10 @@
|
|||
-- Recent additions to add after db init (.gz)
|
||||
-- mysql yaamp -p < file.sql
|
||||
|
||||
-- don't forget to restart memcached service to refresh the db structure
|
||||
|
||||
ALTER TABLE `benchmarks` ADD `realfreq` INT(8) UNSIGNED NULL AFTER `freq`;
|
||||
ALTER TABLE `benchmarks` ADD `realmemf` INT(8) UNSIGNED NULL AFTER `memf`;
|
||||
ALTER TABLE `benchmarks` ADD `plimit` INT(5) UNSIGNED NULL AFTER `power`;
|
||||
ALTER TABLE `benchmarks` DROP COLUMN `mem`;
|
||||
|
5
sql/2017-03-31-earnings_index.sql
Normal file
5
sql/2017-03-31-earnings_index.sql
Normal file
|
@ -0,0 +1,5 @@
|
|||
-- Recent additions to add after db init (.gz)
|
||||
-- mysql yaamp -p < file.sql
|
||||
|
||||
ALTER TABLE `earnings` ADD UNIQUE INDEX `ndx_user_block`(`userid`, `blockid`);
|
||||
|
9
sql/2017-05-accounts_case_swaptime.sql
Normal file
9
sql/2017-05-accounts_case_swaptime.sql
Normal file
|
@ -0,0 +1,9 @@
|
|||
-- Recent additions to add after db init (.gz)
|
||||
-- mysql yaamp -p < file.sql
|
||||
|
||||
-- Adds binary type to be case sensitive
|
||||
ALTER TABLE accounts CHANGE `username` `username` varchar(128) binary NOT NULL;
|
||||
|
||||
-- Remember last coin id swap
|
||||
ALTER TABLE accounts ADD `swap_time` INT(10) UNSIGNED NULL AFTER `coinsymbol`;
|
||||
|
20
sql/2017-06-payouts_coinid_memo.sql
Normal file
20
sql/2017-06-payouts_coinid_memo.sql
Normal file
|
@ -0,0 +1,20 @@
|
|||
-- Recent additions to add after db init (.gz)
|
||||
-- mysql yaamp -p < file.sql
|
||||
|
||||
-- Store coin id used on payment, memoid could be used later for xrp
|
||||
|
||||
ALTER TABLE `payouts`
|
||||
ADD `idcoin` int(11) NULL AFTER `account_id`,
|
||||
ADD `memoid` varchar(128) NULL AFTER `tx`;
|
||||
|
||||
ALTER TABLE `payouts` DROP COLUMN `account_ids`;
|
||||
|
||||
ALTER TABLE `payouts`
|
||||
ADD KEY `payouts_coin` (`idcoin`);
|
||||
|
||||
ALTER TABLE `payouts` ADD CONSTRAINT fk_payouts_coin FOREIGN KEY (`idcoin`)
|
||||
REFERENCES coins (`id`) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE `payouts` ADD CONSTRAINT fk_payouts_account FOREIGN KEY (`account_id`)
|
||||
REFERENCES accounts (`id`) ON DELETE CASCADE;
|
||||
|
6
sql/2017-09-notifications.sql
Normal file
6
sql/2017-09-notifications.sql
Normal file
|
@ -0,0 +1,6 @@
|
|||
-- Recent additions to add after db init (.gz)
|
||||
-- mysql yaamp -p < file.sql
|
||||
|
||||
ALTER TABLE `notifications` CHANGE `lastchecked` `lastchecked` int(10) UNSIGNED NOT NULL DEFAULT '0';
|
||||
ALTER TABLE `notifications` CHANGE `lasttriggered` `lasttriggered` int(10) UNSIGNED NOT NULL DEFAULT '0';
|
||||
|
8
sql/2017-10-bookmarks.sql
Normal file
8
sql/2017-10-bookmarks.sql
Normal file
|
@ -0,0 +1,8 @@
|
|||
-- Recent additions to add after db init (.gz)
|
||||
-- mysql yaamp -p < file.sql
|
||||
|
||||
ALTER TABLE `notifications` CHANGE `lastchecked` `lastchecked` int(10) UNSIGNED NULL;
|
||||
ALTER TABLE `notifications` CHANGE `lasttriggered` `lasttriggered` int(10) UNSIGNED NULL;
|
||||
|
||||
ALTER TABLE `bookmarks` CHANGE `lastused` `lastused` int(10) UNSIGNED NULL;
|
||||
|
7
sql/2017-11-segwit.sql
Normal file
7
sql/2017-11-segwit.sql
Normal file
|
@ -0,0 +1,7 @@
|
|||
-- Recent additions to add after db init (.gz)
|
||||
-- mysql yaamp -p < file.sql
|
||||
|
||||
ALTER TABLE `blocks` ADD `segwit` tinyint(1) UNSIGNED NOT NULL DEFAULT '0' AFTER `txhash`;
|
||||
|
||||
ALTER TABLE `coins` ADD `usesegwit` tinyint(1) UNSIGNED NOT NULL DEFAULT '0' AFTER `usememorypool`;
|
||||
|
17
sql/2018-01-stratums_ports.sql
Normal file
17
sql/2018-01-stratums_ports.sql
Normal file
|
@ -0,0 +1,17 @@
|
|||
-- Recent additions to add after db init (.gz)
|
||||
-- mysql yaamp -p < file.sql
|
||||
|
||||
-- filled by the stratum instance, to allow to handle/watch multiple instances
|
||||
|
||||
ALTER TABLE `stratums` ADD `started` int(11) UNSIGNED NULL AFTER `time`;
|
||||
|
||||
ALTER TABLE `stratums` ADD `workers` int(10) UNSIGNED NOT NULL DEFAULT '0' AFTER `algo`;
|
||||
|
||||
ALTER TABLE `stratums` ADD `port` int(6) UNSIGNED NULL AFTER `workers`;
|
||||
|
||||
ALTER TABLE `stratums` ADD `symbol` varchar(16) NULL AFTER `port`;
|
||||
|
||||
ALTER TABLE `stratums` ADD `url` varchar(128) NULL AFTER `symbol`;
|
||||
|
||||
ALTER TABLE `stratums` ADD `fds` int(10) UNSIGNED NOT NULL DEFAULT '0' AFTER `url`;
|
||||
|
13
sql/2018-02-coins_getinfo.sql
Normal file
13
sql/2018-02-coins_getinfo.sql
Normal file
|
@ -0,0 +1,13 @@
|
|||
-- Recent additions to add after db init (.gz)
|
||||
-- mysql yaamp -p < file.sql
|
||||
|
||||
-- filled by the stratum instance, to allow to handle/watch multiple instances
|
||||
|
||||
ALTER TABLE `coins` ADD `hasgetinfo` tinyint(1) UNSIGNED NOT NULL DEFAULT '1' AFTER `account`;
|
||||
|
||||
UPDATE coins SET hassubmitblock=0 WHERE hassubmitblock IS NULL;
|
||||
UPDATE coins SET hassubmitblock=1 WHERE hassubmitblock > 0;
|
||||
ALTER TABLE `coins` CHANGE `hassubmitblock` `hassubmitblock` tinyint(1) UNSIGNED NOT NULL DEFAULT '1';
|
||||
|
||||
ALTER TABLE `coins` ADD `no_explorer` tinyint(1) UNSIGNED NOT NULL DEFAULT '0' AFTER `visible`;
|
||||
|
|
@ -8,12 +8,6 @@ SQLFLAGS= `mysql_config --cflags --libs`
|
|||
# if you use the auto exchange feature...
|
||||
CFLAGS += -DNO_EXCHANGE
|
||||
|
||||
#CFLAGS += -DHASH_DEBUGLOG_
|
||||
#CFLAGS += -DRPC_DEBUGLOG_
|
||||
#CFLAGS += -DREMOTE_DEBUGLOG_
|
||||
#CFLAGS += -DSOCKET_DEBUGLOG_
|
||||
#CFLAGS += -DCLIENT_DEBUGLOG_
|
||||
|
||||
#CFLAGS=-c -O2 -I /usr/include/mysql
|
||||
LDFLAGS=-O2 `mysql_config --libs`
|
||||
|
||||
|
@ -63,6 +57,7 @@ clean:
|
|||
rm -f algos/*.a
|
||||
rm -f sha3/*.o
|
||||
rm -f sha3/*.a
|
||||
rm -f algos/ar2/*.o
|
||||
|
||||
install: clean all
|
||||
strip -s stratum
|
||||
|
|
250
stratum/algos/Lyra2-z.c
Executable file
250
stratum/algos/Lyra2-z.c
Executable file
|
@ -0,0 +1,250 @@
|
|||
/**
|
||||
* Implementation of the Lyra2 Password Hashing Scheme (PHS).
|
||||
*
|
||||
* Author: The Lyra PHC team (http://www.lyra-kdf.net/) -- 2014.
|
||||
*
|
||||
* This software is hereby placed in the public domain.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''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 AUTHORS 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.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include "Lyra2.h"
|
||||
#include "Sponge.h"
|
||||
|
||||
static __thread uint64_t *wholeMatrix = NULL;
|
||||
static __thread uint64_t **memMatrix = NULL;
|
||||
static __thread uint64_t curRows = 0;
|
||||
|
||||
/**
|
||||
* Executes Lyra2 based on the G function from Blake2b. This version supports salts and passwords
|
||||
* whose combined length is smaller than the size of the memory matrix, (i.e., (nRows x nCols x b) bits,
|
||||
* where "b" is the underlying sponge's bitrate). In this implementation, the "basil" is composed by all
|
||||
* integer parameters (treated as type "unsigned int") in the order they are provided, plus the value
|
||||
* of nCols, (i.e., basil = kLen || pwdlen || saltlen || timeCost || nRows || nCols).
|
||||
*
|
||||
* @param K The derived key to be output by the algorithm
|
||||
* @param kLen Desired key length
|
||||
* @param pwd User password
|
||||
* @param pwdlen Password length
|
||||
* @param salt Salt
|
||||
* @param saltlen Salt length
|
||||
* @param timeCost Parameter to determine the processing time (T)
|
||||
* @param nRows Number or rows of the memory matrix (R)
|
||||
* @param nCols Number of columns of the memory matrix (C)
|
||||
*
|
||||
* @return 0 if the key is generated correctly; -1 if there is an error (usually due to lack of memory for allocation)
|
||||
*/
|
||||
int LYRA2z(void *K, uint64_t kLen, const void *pwd, uint64_t pwdlen, const void *salt, uint64_t saltlen, uint64_t timeCost, uint64_t nRows, uint64_t nCols) {
|
||||
|
||||
//============================= Basic variables ============================//
|
||||
int64_t row = 2; //index of row to be processed
|
||||
int64_t prev = 1; //index of prev (last row ever computed/modified)
|
||||
int64_t rowa = 0; //index of row* (a previous row, deterministically picked during Setup and randomly picked while Wandering)
|
||||
int64_t tau; //Time Loop iterator
|
||||
int64_t step = 1; //Visitation step (used during Setup and Wandering phases)
|
||||
int64_t window = 2; //Visitation window (used to define which rows can be revisited during Setup)
|
||||
int64_t gap = 1; //Modifier to the step, assuming the values 1 or -1
|
||||
int64_t i; //auxiliary iteration counter
|
||||
//==========================================================================/
|
||||
|
||||
//========== Initializing the Memory Matrix and pointers to it =============//
|
||||
//Tries to allocate enough space for the whole memory matrix
|
||||
|
||||
|
||||
const int64_t ROW_LEN_INT64 = BLOCK_LEN_INT64 * nCols;
|
||||
const int64_t ROW_LEN_BYTES = ROW_LEN_INT64 * 8;
|
||||
|
||||
|
||||
uint64_t *ptrWord = wholeMatrix;
|
||||
|
||||
if (!wholeMatrix || !memMatrix) {
|
||||
curRows = nRows + 32;
|
||||
i = (int64_t) ((int64_t) curRows * (int64_t) ROW_LEN_BYTES);
|
||||
wholeMatrix = (uint64_t*) malloc(i);
|
||||
if (wholeMatrix == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
//Allocates pointers to each row of the matrix
|
||||
memMatrix = malloc(sizeof(uint64_t*) * curRows);
|
||||
if (memMatrix == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
//Places the pointers in the correct positions
|
||||
ptrWord = wholeMatrix;
|
||||
for (i = 0; i < curRows; i++) {
|
||||
memMatrix[i] = ptrWord;
|
||||
ptrWord += ROW_LEN_INT64;
|
||||
}
|
||||
} else {
|
||||
if (nRows > curRows) {
|
||||
free(memMatrix); memMatrix = NULL;
|
||||
free(wholeMatrix); wholeMatrix = NULL;
|
||||
return -2;
|
||||
}
|
||||
memset(wholeMatrix, 0, nRows * ROW_LEN_BYTES);
|
||||
}
|
||||
/*
|
||||
i = (int64_t) ((int64_t) nRows * (int64_t) ROW_LEN_BYTES);
|
||||
uint64_t *wholeMatrix = malloc(i);
|
||||
if (wholeMatrix == NULL) {
|
||||
return -1;
|
||||
}
|
||||
memset(wholeMatrix, 0, i);
|
||||
|
||||
//Allocates pointers to each row of the matrix
|
||||
uint64_t **memMatrix = malloc(nRows * sizeof (uint64_t*));
|
||||
if (memMatrix == NULL) {
|
||||
return -1;
|
||||
}
|
||||
//Places the pointers in the correct positions
|
||||
uint64_t *ptrWord = wholeMatrix;
|
||||
for (i = 0; i < nRows; i++) {
|
||||
memMatrix[i] = ptrWord;
|
||||
ptrWord += ROW_LEN_INT64;
|
||||
}
|
||||
*/
|
||||
//==========================================================================/
|
||||
|
||||
//============= Getting the password + salt + basil padded with 10*1 ===============//
|
||||
//OBS.:The memory matrix will temporarily hold the password: not for saving memory,
|
||||
//but this ensures that the password copied locally will be overwritten as soon as possible
|
||||
|
||||
//First, we clean enough blocks for the password, salt, basil and padding
|
||||
uint64_t nBlocksInput = ((saltlen + pwdlen + 6 * sizeof (uint64_t)) / BLOCK_LEN_BLAKE2_SAFE_BYTES) + 1;
|
||||
byte *ptrByte = (byte*) wholeMatrix;
|
||||
memset(ptrByte, 0, nBlocksInput * BLOCK_LEN_BLAKE2_SAFE_BYTES);
|
||||
|
||||
//Prepends the password
|
||||
memcpy(ptrByte, pwd, pwdlen);
|
||||
ptrByte += pwdlen;
|
||||
|
||||
//Concatenates the salt
|
||||
memcpy(ptrByte, salt, saltlen);
|
||||
ptrByte += saltlen;
|
||||
|
||||
//Concatenates the basil: every integer passed as parameter, in the order they are provided by the interface
|
||||
memcpy(ptrByte, &kLen, sizeof (uint64_t));
|
||||
ptrByte += sizeof (uint64_t);
|
||||
memcpy(ptrByte, &pwdlen, sizeof (uint64_t));
|
||||
ptrByte += sizeof (uint64_t);
|
||||
memcpy(ptrByte, &saltlen, sizeof (uint64_t));
|
||||
ptrByte += sizeof (uint64_t);
|
||||
memcpy(ptrByte, &timeCost, sizeof (uint64_t));
|
||||
ptrByte += sizeof (uint64_t);
|
||||
memcpy(ptrByte, &nRows, sizeof (uint64_t));
|
||||
ptrByte += sizeof (uint64_t);
|
||||
memcpy(ptrByte, &nCols, sizeof (uint64_t));
|
||||
ptrByte += sizeof (uint64_t);
|
||||
|
||||
//Now comes the padding
|
||||
*ptrByte = 0x80; //first byte of padding: right after the password
|
||||
ptrByte = (byte*) wholeMatrix; //resets the pointer to the start of the memory matrix
|
||||
ptrByte += nBlocksInput * BLOCK_LEN_BLAKE2_SAFE_BYTES - 1; //sets the pointer to the correct position: end of incomplete block
|
||||
*ptrByte ^= 0x01; //last byte of padding: at the end of the last incomplete block
|
||||
//==========================================================================/
|
||||
|
||||
//======================= Initializing the Sponge State ====================//
|
||||
//Sponge state: 16 uint64_t, BLOCK_LEN_INT64 words of them for the bitrate (b) and the remainder for the capacity (c)
|
||||
uint64_t *state = malloc(16 * sizeof (uint64_t));
|
||||
if (state == NULL) {
|
||||
return -1;
|
||||
}
|
||||
initState(state);
|
||||
//==========================================================================/
|
||||
|
||||
//================================ Setup Phase =============================//
|
||||
//Absorbing salt, password and basil: this is the only place in which the block length is hard-coded to 512 bits
|
||||
ptrWord = wholeMatrix;
|
||||
for (i = 0; i < nBlocksInput; i++) {
|
||||
absorbBlockBlake2Safe(state, ptrWord); //absorbs each block of pad(pwd || salt || basil)
|
||||
ptrWord += BLOCK_LEN_BLAKE2_SAFE_INT64; //goes to next block of pad(pwd || salt || basil)
|
||||
}
|
||||
|
||||
//Initializes M[0] and M[1]
|
||||
reducedSqueezeRow0(state, memMatrix[0], nCols); //The locally copied password is most likely overwritten here
|
||||
reducedDuplexRow1(state, memMatrix[0], memMatrix[1], nCols);
|
||||
|
||||
do {
|
||||
//M[row] = rand; //M[row*] = M[row*] XOR rotW(rand)
|
||||
reducedDuplexRowSetup(state, memMatrix[prev], memMatrix[rowa], memMatrix[row], nCols);
|
||||
|
||||
|
||||
//updates the value of row* (deterministically picked during Setup))
|
||||
rowa = (rowa + step) & (window - 1);
|
||||
//update prev: it now points to the last row ever computed
|
||||
prev = row;
|
||||
//updates row: goes to the next row to be computed
|
||||
row++;
|
||||
|
||||
//Checks if all rows in the window where visited.
|
||||
if (rowa == 0) {
|
||||
step = window + gap; //changes the step: approximately doubles its value
|
||||
window *= 2; //doubles the size of the re-visitation window
|
||||
gap = -gap; //inverts the modifier to the step
|
||||
}
|
||||
|
||||
} while (row < nRows);
|
||||
//==========================================================================/
|
||||
|
||||
//============================ Wandering Phase =============================//
|
||||
row = 0; //Resets the visitation to the first row of the memory matrix
|
||||
for (tau = 1; tau <= timeCost; tau++) {
|
||||
//Step is approximately half the number of all rows of the memory matrix for an odd tau; otherwise, it is -1
|
||||
step = (tau % 2 == 0) ? -1 : nRows / 2 - 1;
|
||||
do {
|
||||
//Selects a pseudorandom index row*
|
||||
//------------------------------------------------------------------------------------------
|
||||
//rowa = ((unsigned int)state[0]) & (nRows-1); //(USE THIS IF nRows IS A POWER OF 2)
|
||||
rowa = ((uint64_t) (state[0])) % nRows; //(USE THIS FOR THE "GENERIC" CASE)
|
||||
//------------------------------------------------------------------------------------------
|
||||
|
||||
//Performs a reduced-round duplexing operation over M[row*] XOR M[prev], updating both M[row*] and M[row]
|
||||
reducedDuplexRow(state, memMatrix[prev], memMatrix[rowa], memMatrix[row], nCols);
|
||||
|
||||
//update prev: it now points to the last row ever computed
|
||||
prev = row;
|
||||
|
||||
//updates row: goes to the next row to be computed
|
||||
//------------------------------------------------------------------------------------------
|
||||
//row = (row + step) & (nRows-1); //(USE THIS IF nRows IS A POWER OF 2)
|
||||
row = (row + step) % nRows; //(USE THIS FOR THE "GENERIC" CASE)
|
||||
//------------------------------------------------------------------------------------------
|
||||
|
||||
} while (row != 0);
|
||||
}
|
||||
//==========================================================================/
|
||||
|
||||
//============================ Wrap-up Phase ===============================//
|
||||
//Absorbs the last block of the memory matrix
|
||||
absorbBlock(state, memMatrix[rowa]);
|
||||
|
||||
//Squeezes the key
|
||||
squeeze(state, K, kLen);
|
||||
//==========================================================================/
|
||||
|
||||
//========================= Freeing the memory =============================//
|
||||
//free(memMatrix);
|
||||
//free(wholeMatrix);
|
||||
|
||||
//Wiping out the sponge's internal state before freeing it
|
||||
memset(state, 0, 16 * sizeof (uint64_t));
|
||||
free(state);
|
||||
//==========================================================================/
|
||||
|
||||
return 0;
|
||||
}
|
51
stratum/algos/Lyra2-z.h
Executable file
51
stratum/algos/Lyra2-z.h
Executable file
|
@ -0,0 +1,51 @@
|
|||
/**
|
||||
* Header file for the Lyra2 Password Hashing Scheme (PHS).
|
||||
*
|
||||
* Author: The Lyra PHC team (http://www.lyra-kdf.net/) -- 2014.
|
||||
*
|
||||
* This software is hereby placed in the public domain.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''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 AUTHORS 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 LYRA2z_H_
|
||||
#define LYRA2z_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef unsigned char byte;
|
||||
|
||||
//Block length required so Blake2's Initialization Vector (IV) is not overwritten (THIS SHOULD NOT BE MODIFIED)
|
||||
#define BLOCK_LEN_BLAKE2_SAFE_INT64 8 //512 bits (=64 bytes, =8 uint64_t)
|
||||
#define BLOCK_LEN_BLAKE2_SAFE_BYTES (BLOCK_LEN_BLAKE2_SAFE_INT64 * 8) //same as above, in bytes
|
||||
|
||||
|
||||
#ifdef BLOCK_LEN_BITS
|
||||
#define BLOCK_LEN_INT64 (BLOCK_LEN_BITS/64) //Block length: 768 bits (=96 bytes, =12 uint64_t)
|
||||
#define BLOCK_LEN_BYTES (BLOCK_LEN_BITS/8) //Block length, in bytes
|
||||
#else //default block lenght: 768 bits
|
||||
#define BLOCK_LEN_INT64 12 //Block length: 768 bits (=96 bytes, =12 uint64_t)
|
||||
#define BLOCK_LEN_BYTES (BLOCK_LEN_INT64 * 8) //Block length, in bytes
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int LYRA2z(void *K, uint64_t kLen, const void *pwd, uint64_t pwdlen, const void *salt, uint64_t saltlen, uint64_t timeCost, uint64_t nRows, uint64_t nCols);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* LYRA2z_H_ */
|
210
stratum/algos/Lyra2-zz.c
Normal file
210
stratum/algos/Lyra2-zz.c
Normal file
|
@ -0,0 +1,210 @@
|
|||
/**
|
||||
* Implementation of the Lyra2 Password Hashing Scheme (PHS).
|
||||
*
|
||||
* Author: The Lyra PHC team (http://www.lyra-kdf.net/) -- 2014.
|
||||
*
|
||||
* This software is hereby placed in the public domain.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''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 AUTHORS 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.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "Lyra2-zz.h"
|
||||
#include "Sponge.h"
|
||||
|
||||
/**
|
||||
* Executes Lyra2 based on the G function from Blake2b. This version supports salts and passwords
|
||||
* whose combined length is smaller than the size of the memory matrix, (i.e., (nRows x nCols x b) bits,
|
||||
* where "b" is the underlying sponge's bitrate). In this implementation, the "basil" is composed by all
|
||||
* integer parameters (treated as type "unsigned int") in the order they are provided, plus the value
|
||||
* of nCols, (i.e., basil = kLen || pwdlen || saltlen || timeCost || nRows || nCols).
|
||||
*
|
||||
* @param K The derived key to be output by the algorithm
|
||||
* @param kLen Desired key length
|
||||
* @param pwd User password
|
||||
* @param pwdlen Password length
|
||||
* @param salt Salt
|
||||
* @param saltlen Salt length
|
||||
* @param timeCost Parameter to determine the processing time (T)
|
||||
* @param nRows Number or rows of the memory matrix (R)
|
||||
* @param nCols Number of columns of the memory matrix (C)
|
||||
*
|
||||
* @return 0 if the key is generated correctly; -1 if there is an error (usually due to lack of memory for allocation)
|
||||
*/
|
||||
int LYRA2ZZ(void *K, uint64_t kLen, const void *pwd, uint64_t pwdlen, const void *salt, uint64_t saltlen, uint64_t timeCost, uint64_t nRows, uint64_t nCols)
|
||||
{
|
||||
//============================= Basic variables ============================//
|
||||
int64_t row = 2; //index of row to be processed
|
||||
int64_t prev = 1; //index of prev (last row ever computed/modified)
|
||||
int64_t rowa = 0; //index of row* (a previous row, deterministically picked during Setup and randomly picked while Wandering)
|
||||
int64_t tau; //Time Loop iterator
|
||||
int64_t step = 1; //Visitation step (used during Setup and Wandering phases)
|
||||
int64_t window = 2; //Visitation window (used to define which rows can be revisited during Setup)
|
||||
int64_t gap = 1; //Modifier to the step, assuming the values 1 or -1
|
||||
int64_t i; //auxiliary iteration counter
|
||||
//==========================================================================/
|
||||
|
||||
//========== Initializing the Memory Matrix and pointers to it =============//
|
||||
//Tries to allocate enough space for the whole memory matrix
|
||||
const int64_t ROW_LEN_INT64 = BLOCK_LEN_INT64 * nCols;
|
||||
const int64_t ROW_LEN_BYTES = ROW_LEN_INT64 * 8;
|
||||
|
||||
i = (int64_t) ((int64_t) nRows * (int64_t) ROW_LEN_BYTES);
|
||||
uint64_t *wholeMatrix = malloc(i);
|
||||
if (wholeMatrix == NULL) {
|
||||
return -1;
|
||||
}
|
||||
memset(wholeMatrix, 0, i);
|
||||
|
||||
//Allocates pointers to each row of the matrix
|
||||
uint64_t **memMatrix = malloc(nRows * sizeof (uint64_t*));
|
||||
if (memMatrix == NULL) {
|
||||
return -1;
|
||||
}
|
||||
//Places the pointers in the correct positions
|
||||
uint64_t *ptrWord = wholeMatrix;
|
||||
for (i = 0; i < nRows; i++) {
|
||||
memMatrix[i] = ptrWord;
|
||||
ptrWord += ROW_LEN_INT64;
|
||||
}
|
||||
//==========================================================================/
|
||||
|
||||
//============= Getting the password + salt + basil padded with 10*1 ===============//
|
||||
//OBS.:The memory matrix will temporarily hold the password: not for saving memory,
|
||||
//but this ensures that the password copied locally will be overwritten as soon as possible
|
||||
|
||||
//First, we clean enough blocks for the password, salt, basil and padding
|
||||
uint64_t nBlocksInput = ((saltlen + pwdlen + 6 * sizeof (uint64_t)) / BLOCK_LEN_BLAKE2_SAFE_BYTES) + 1;
|
||||
byte *ptrByte = (byte*) wholeMatrix;
|
||||
memset(ptrByte, 0, nBlocksInput * BLOCK_LEN_BLAKE2_SAFE_BYTES);
|
||||
|
||||
//Prepends the password
|
||||
memcpy(ptrByte, pwd, pwdlen);
|
||||
ptrByte += pwdlen;
|
||||
|
||||
//Concatenates the salt
|
||||
memcpy(ptrByte, salt, saltlen);
|
||||
ptrByte += saltlen;
|
||||
|
||||
//Concatenates the basil: every integer passed as parameter, in the order they are provided by the interface
|
||||
memcpy(ptrByte, &kLen, sizeof (uint64_t));
|
||||
ptrByte += sizeof (uint64_t);
|
||||
memcpy(ptrByte, &pwdlen, sizeof (uint64_t));
|
||||
ptrByte += sizeof (uint64_t);
|
||||
memcpy(ptrByte, &saltlen, sizeof (uint64_t));
|
||||
ptrByte += sizeof (uint64_t);
|
||||
memcpy(ptrByte, &timeCost, sizeof (uint64_t));
|
||||
ptrByte += sizeof (uint64_t);
|
||||
memcpy(ptrByte, &nRows, sizeof (uint64_t));
|
||||
ptrByte += sizeof (uint64_t);
|
||||
memcpy(ptrByte, &nCols, sizeof (uint64_t));
|
||||
ptrByte += sizeof (uint64_t);
|
||||
|
||||
//Now comes the padding
|
||||
*ptrByte = 0x80; //first byte of padding: right after the password
|
||||
ptrByte = (byte*) wholeMatrix; //resets the pointer to the start of the memory matrix
|
||||
ptrByte += nBlocksInput * BLOCK_LEN_BLAKE2_SAFE_BYTES - 1; //sets the pointer to the correct position: end of incomplete block
|
||||
*ptrByte ^= 0x01; //last byte of padding: at the end of the last incomplete block
|
||||
//==========================================================================/
|
||||
|
||||
//======================= Initializing the Sponge State ====================//
|
||||
//Sponge state: 16 uint64_t, BLOCK_LEN_INT64 words of them for the bitrate (b) and the remainder for the capacity (c)
|
||||
uint64_t *state = malloc(16 * sizeof (uint64_t));
|
||||
if (state == NULL) {
|
||||
return -1;
|
||||
}
|
||||
initState(state);
|
||||
//==========================================================================/
|
||||
|
||||
//================================ Setup Phase =============================//
|
||||
//Absorbing salt, password and basil: this is the only place in which the block length is hard-coded to 512 bits
|
||||
ptrWord = wholeMatrix;
|
||||
for (i = 0; i < nBlocksInput; i++) {
|
||||
absorbBlockBlake2Safe(state, ptrWord); //absorbs each block of pad(pwd || salt || basil)
|
||||
ptrWord += BLOCK_LEN_BLAKE2_SAFE_INT64; //goes to next block of pad(pwd || salt || basil)
|
||||
}
|
||||
|
||||
//Initializes M[0] and M[1]
|
||||
reducedSqueezeRow0(state, memMatrix[0], nCols); //The locally copied password is most likely overwritten here
|
||||
reducedDuplexRow1(state, memMatrix[0], memMatrix[1], nCols);
|
||||
|
||||
do {
|
||||
//M[row] = rand; //M[row*] = M[row*] XOR rotW(rand)
|
||||
reducedDuplexRowSetup(state, memMatrix[prev], memMatrix[rowa], memMatrix[row], nCols);
|
||||
|
||||
//updates the value of row* (deterministically picked during Setup))
|
||||
rowa = (rowa + step) & (window - 1);
|
||||
//update prev: it now points to the last row ever computed
|
||||
prev = row;
|
||||
//updates row: goes to the next row to be computed
|
||||
row++;
|
||||
|
||||
//Checks if all rows in the window where visited.
|
||||
if (rowa == 0) {
|
||||
step = window + gap; //changes the step: approximately doubles its value
|
||||
window *= 2; //doubles the size of the re-visitation window
|
||||
gap = -gap; //inverts the modifier to the step
|
||||
}
|
||||
|
||||
} while (row < nRows);
|
||||
//==========================================================================/
|
||||
|
||||
//============================ Wandering Phase =============================//
|
||||
row = 0; //Resets the visitation to the first row of the memory matrix
|
||||
for (tau = 1; tau <= timeCost; tau++) {
|
||||
//Step is approximately half the number of all rows of the memory matrix for an odd tau; otherwise, it is -1
|
||||
step = (tau % 2 == 0) ? -1 : nRows / 2 - 1;
|
||||
do {
|
||||
//Selects a pseudorandom index row*
|
||||
//------------------------------------------------------------------------------------------
|
||||
//rowa = ((unsigned int)state[0]) & (nRows-1); //(USE THIS IF nRows IS A POWER OF 2)
|
||||
rowa = ((uint64_t) (state[0])) % nRows; //(USE THIS FOR THE "GENERIC" CASE)
|
||||
//------------------------------------------------------------------------------------------
|
||||
|
||||
//Performs a reduced-round duplexing operation over M[row*] XOR M[prev], updating both M[row*] and M[row]
|
||||
reducedDuplexRow(state, memMatrix[prev], memMatrix[rowa], memMatrix[row], nCols);
|
||||
|
||||
//update prev: it now points to the last row ever computed
|
||||
prev = row;
|
||||
|
||||
//updates row: goes to the next row to be computed
|
||||
//------------------------------------------------------------------------------------------
|
||||
//row = (row + step) & (nRows-1); //(USE THIS IF nRows IS A POWER OF 2)
|
||||
row = (row + step) % nRows; //(USE THIS FOR THE "GENERIC" CASE)
|
||||
//------------------------------------------------------------------------------------------
|
||||
} while (row != 0);
|
||||
}
|
||||
//==========================================================================/
|
||||
|
||||
//============================ Wrap-up Phase ===============================//
|
||||
//Absorbs the last block of the memory matrix
|
||||
absorbBlock(state, memMatrix[rowa]);
|
||||
|
||||
//Squeezes the key
|
||||
squeeze(state, K, kLen);
|
||||
//==========================================================================/
|
||||
|
||||
//========================= Freeing the memory =============================//
|
||||
free(memMatrix);
|
||||
free(wholeMatrix);
|
||||
|
||||
//Wiping out the sponge's internal state before freeing it
|
||||
memset(state, 0, 16 * sizeof (uint64_t));
|
||||
free(state);
|
||||
//==========================================================================/
|
||||
|
||||
return 0;
|
||||
}
|
55
stratum/algos/Lyra2-zz.h
Normal file
55
stratum/algos/Lyra2-zz.h
Normal file
|
@ -0,0 +1,55 @@
|
|||
/**
|
||||
* Header file for the Lyra2 Password Hashing Scheme (PHS).
|
||||
*
|
||||
* Author: The Lyra PHC team (http://www.lyra-kdf.net/) -- 2014.
|
||||
*
|
||||
* This software is hereby placed in the public domain.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''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 AUTHORS 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 LYRA2ZZ_H_
|
||||
#define LYRA2ZZ_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef unsigned char byte;
|
||||
|
||||
//Block length required so Blake2's Initialization Vector (IV) is not overwritten (THIS SHOULD NOT BE MODIFIED)
|
||||
#define BLOCK_LEN_BLAKE2_SAFE_INT64 12 //768 bits (=96 bytes, =12 uint64_t)
|
||||
#define BLOCK_LEN_BLAKE2_SAFE_BYTES (BLOCK_LEN_BLAKE2_SAFE_INT64 * 8) //same as above, in bytes
|
||||
|
||||
#define LYRA2ZZ_BLOCK_HEADER_LEN_BYTES 112
|
||||
#define LYRA2ZZ_BLOCK_HEADER_NONCE_OFFSET 19 /* 19 * 4 bytes */
|
||||
|
||||
#define LYRA2ZZ_BLOCK_HEADER_UINT32_LEN 32
|
||||
|
||||
#ifdef BLOCK_LEN_BITS
|
||||
#define BLOCK_LEN_INT64 (BLOCK_LEN_BITS/64) //Block length: 1024 bits (=128 bytes, =16 uint64_t)
|
||||
#define BLOCK_LEN_BYTES (BLOCK_LEN_BITS/8) //Block length, in bytes
|
||||
#else //default block length: 1024 bits
|
||||
#define BLOCK_LEN_INT64 16 //Block length: 1024 bits (=128 bytes, =16 uint64_t)
|
||||
#define BLOCK_LEN_BYTES (BLOCK_LEN_INT64 * 8) //Block length, in bytes
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int LYRA2ZZ(void *K, uint64_t kLen, const void *pwd, uint64_t pwdlen, const void *salt, uint64_t saltlen, uint64_t timeCost, uint64_t nRows, uint64_t nCols);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* LYRA2ZZ_H_ */
|
|
@ -164,10 +164,10 @@ int LYRA2(void *K, int64_t kLen, const void *pwd, int32_t pwdlen, const void *sa
|
|||
|
||||
//Checks if all rows in the window where visited.
|
||||
if (rowa == 0) {
|
||||
step = window + gap; //changes the step: approximately doubles its value
|
||||
window *= 2; //doubles the size of the re-visitation window
|
||||
gap = -gap; //inverts the modifier to the step
|
||||
}
|
||||
step = window + gap; //changes the step: approximately doubles its value
|
||||
window *= 2; //doubles the size of the re-visitation window
|
||||
gap = -gap; //inverts the modifier to the step
|
||||
}
|
||||
|
||||
} while (row < nRows);
|
||||
//==========================================================================/
|
||||
|
@ -212,3 +212,175 @@ int LYRA2(void *K, int64_t kLen, const void *pwd, int32_t pwdlen, const void *sa
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int LYRA2_3(void *K, int64_t kLen, const void *pwd, int32_t pwdlen, const void *salt, int32_t saltlen, int64_t timeCost, const int16_t nRows, const int16_t nCols)
|
||||
{
|
||||
//============================= Basic variables ============================//
|
||||
int64_t row = 2; //index of row to be processed
|
||||
int64_t prev = 1; //index of prev (last row ever computed/modified)
|
||||
int64_t rowa = 0; //index of row* (a previous row, deterministically picked during Setup and randomly picked while Wandering)
|
||||
int64_t tau; //Time Loop iterator
|
||||
int64_t step = 1; //Visitation step (used during Setup and Wandering phases)
|
||||
int64_t window = 2; //Visitation window (used to define which rows can be revisited during Setup)
|
||||
int64_t gap = 1; //Modifier to the step, assuming the values 1 or -1
|
||||
int64_t i; //auxiliary iteration counter
|
||||
int64_t v64; // 64bit var for memcpy
|
||||
uint64_t instance = 0;
|
||||
//==========================================================================/
|
||||
|
||||
//========== Initializing the Memory Matrix and pointers to it =============//
|
||||
//Tries to allocate enough space for the whole memory matrix
|
||||
|
||||
const int64_t ROW_LEN_INT64 = BLOCK_LEN_INT64 * nCols;
|
||||
const int64_t ROW_LEN_BYTES = ROW_LEN_INT64 * 8;
|
||||
const int64_t BLOCK_LEN = BLOCK_LEN_BLAKE2_SAFE_INT64;
|
||||
|
||||
size_t sz = (size_t)ROW_LEN_BYTES * nRows;
|
||||
uint64_t *wholeMatrix = malloc(sz);
|
||||
if (wholeMatrix == NULL) {
|
||||
return -1;
|
||||
}
|
||||
memset(wholeMatrix, 0, sz);
|
||||
|
||||
//Allocates pointers to each row of the matrix
|
||||
uint64_t **memMatrix = malloc(sizeof(uint64_t*) * nRows);
|
||||
if (memMatrix == NULL) {
|
||||
return -1;
|
||||
}
|
||||
//Places the pointers in the correct positions
|
||||
uint64_t *ptrWord = wholeMatrix;
|
||||
for (i = 0; i < nRows; i++) {
|
||||
memMatrix[i] = ptrWord;
|
||||
ptrWord += ROW_LEN_INT64;
|
||||
}
|
||||
//==========================================================================/
|
||||
|
||||
//============= Getting the password + salt + basil padded with 10*1 ===============//
|
||||
//OBS.:The memory matrix will temporarily hold the password: not for saving memory,
|
||||
//but this ensures that the password copied locally will be overwritten as soon as possible
|
||||
|
||||
//First, we clean enough blocks for the password, salt, basil and padding
|
||||
int64_t nBlocksInput = ((saltlen + pwdlen + 6 * sizeof(uint64_t)) / BLOCK_LEN_BLAKE2_SAFE_BYTES) + 1;
|
||||
|
||||
byte *ptrByte = (byte*) wholeMatrix;
|
||||
|
||||
//Prepends the password
|
||||
memcpy(ptrByte, pwd, pwdlen);
|
||||
ptrByte += pwdlen;
|
||||
|
||||
//Concatenates the salt
|
||||
memcpy(ptrByte, salt, saltlen);
|
||||
ptrByte += saltlen;
|
||||
|
||||
memset(ptrByte, 0, (size_t) (nBlocksInput * BLOCK_LEN_BLAKE2_SAFE_BYTES - (saltlen + pwdlen)));
|
||||
|
||||
//Concatenates the basil: every integer passed as parameter, in the order they are provided by the interface
|
||||
memcpy(ptrByte, &kLen, sizeof(int64_t));
|
||||
ptrByte += sizeof(uint64_t);
|
||||
v64 = pwdlen;
|
||||
memcpy(ptrByte, &v64, sizeof(int64_t));
|
||||
ptrByte += sizeof(uint64_t);
|
||||
v64 = saltlen;
|
||||
memcpy(ptrByte, &v64, sizeof(int64_t));
|
||||
ptrByte += sizeof(uint64_t);
|
||||
v64 = timeCost;
|
||||
memcpy(ptrByte, &v64, sizeof(int64_t));
|
||||
ptrByte += sizeof(uint64_t);
|
||||
v64 = nRows;
|
||||
memcpy(ptrByte, &v64, sizeof(int64_t));
|
||||
ptrByte += sizeof(uint64_t);
|
||||
v64 = nCols;
|
||||
memcpy(ptrByte, &v64, sizeof(int64_t));
|
||||
ptrByte += sizeof(uint64_t);
|
||||
|
||||
//Now comes the padding
|
||||
*ptrByte = 0x80; //first byte of padding: right after the password
|
||||
ptrByte = (byte*) wholeMatrix; //resets the pointer to the start of the memory matrix
|
||||
ptrByte += nBlocksInput * BLOCK_LEN_BLAKE2_SAFE_BYTES - 1; //sets the pointer to the correct position: end of incomplete block
|
||||
*ptrByte ^= 0x01; //last byte of padding: at the end of the last incomplete block
|
||||
//==========================================================================/
|
||||
|
||||
//======================= Initializing the Sponge State ====================//
|
||||
//Sponge state: 16 uint64_t, BLOCK_LEN_INT64 words of them for the bitrate (b) and the remainder for the capacity (c)
|
||||
uint64_t state[16];
|
||||
initState(state);
|
||||
//==========================================================================/
|
||||
|
||||
//================================ Setup Phase =============================//
|
||||
//Absorbing salt, password and basil: this is the only place in which the block length is hard-coded to 512 bits
|
||||
ptrWord = wholeMatrix;
|
||||
for (i = 0; i < nBlocksInput; i++) {
|
||||
absorbBlockBlake2Safe(state, ptrWord); //absorbs each block of pad(pwd || salt || basil)
|
||||
ptrWord += BLOCK_LEN; //goes to next block of pad(pwd || salt || basil)
|
||||
}
|
||||
|
||||
//Initializes M[0] and M[1]
|
||||
reducedSqueezeRow0(state, memMatrix[0], nCols); //The locally copied password is most likely overwritten here
|
||||
|
||||
reducedDuplexRow1(state, memMatrix[0], memMatrix[1], nCols);
|
||||
|
||||
do {
|
||||
//M[row] = rand; //M[row*] = M[row*] XOR rotW(rand)
|
||||
|
||||
reducedDuplexRowSetup(state, memMatrix[prev], memMatrix[rowa], memMatrix[row], nCols);
|
||||
|
||||
//updates the value of row* (deterministically picked during Setup))
|
||||
rowa = (rowa + step) & (window - 1);
|
||||
//update prev: it now points to the last row ever computed
|
||||
prev = row;
|
||||
//updates row: goes to the next row to be computed
|
||||
row++;
|
||||
|
||||
//Checks if all rows in the window where visited.
|
||||
if (rowa == 0) {
|
||||
step = window + gap; //changes the step: approximately doubles its value
|
||||
window *= 2; //doubles the size of the re-visitation window
|
||||
gap = -gap; //inverts the modifier to the step
|
||||
}
|
||||
|
||||
} while (row < nRows);
|
||||
//==========================================================================/
|
||||
|
||||
//============================ Wandering Phase =============================//
|
||||
row = 0; //Resets the visitation to the first row of the memory matrix
|
||||
for (tau = 1; tau <= timeCost; tau++) {
|
||||
//Step is approximately half the number of all rows of the memory matrix for an odd tau; otherwise, it is -1
|
||||
step = ((tau & 1) == 0) ? -1 : (nRows >> 1) - 1;
|
||||
do {
|
||||
//Selects a pseudorandom index row*
|
||||
//------------------------------------------------------------------------------------------
|
||||
instance = state[instance & 0xF];
|
||||
rowa = state[instance & 0xF] & (unsigned int)(nRows-1);
|
||||
|
||||
//rowa = state[0] & (unsigned int)(nRows-1); //(USE THIS IF nRows IS A POWER OF 2)
|
||||
//rowa = state[0] % nRows; //(USE THIS FOR THE "GENERIC" CASE)
|
||||
//------------------------------------------------------------------------------------------
|
||||
|
||||
//Performs a reduced-round duplexing operation over M[row*] XOR M[prev], updating both M[row*] and M[row]
|
||||
reducedDuplexRow(state, memMatrix[prev], memMatrix[rowa], memMatrix[row], nCols);
|
||||
|
||||
//update prev: it now points to the last row ever computed
|
||||
prev = row;
|
||||
|
||||
//updates row: goes to the next row to be computed
|
||||
//------------------------------------------------------------------------------------------
|
||||
row = (row + step) & (unsigned int)(nRows-1); //(USE THIS IF nRows IS A POWER OF 2)
|
||||
//row = (row + step) % nRows; //(USE THIS FOR THE "GENERIC" CASE)
|
||||
//------------------------------------------------------------------------------------------
|
||||
|
||||
} while (row != 0);
|
||||
}
|
||||
|
||||
//============================ Wrap-up Phase ===============================//
|
||||
//Absorbs the last block of the memory matrix
|
||||
absorbBlock(state, memMatrix[rowa]);
|
||||
|
||||
//Squeezes the key
|
||||
squeeze(state, K, (unsigned int) kLen);
|
||||
|
||||
//========================= Freeing the memory =============================//
|
||||
free(memMatrix);
|
||||
free(wholeMatrix);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -39,4 +39,6 @@ typedef unsigned char byte;
|
|||
|
||||
int LYRA2(void *K, int64_t kLen, const void *pwd, int32_t pwdlen, const void *salt, int32_t saltlen, int64_t timeCost, const int16_t nRows, const int16_t nCols);
|
||||
|
||||
int LYRA2_3(void *K, int64_t kLen, const void *pwd, int32_t pwdlen, const void *salt, int32_t saltlen, int64_t timeCost, const int16_t nRows, const int16_t nCols);
|
||||
|
||||
#endif /* LYRA2_H_ */
|
||||
|
|
1155
stratum/algos/SWIFFTX/SWIFFTX.c
Normal file
1155
stratum/algos/SWIFFTX/SWIFFTX.c
Normal file
File diff suppressed because it is too large
Load diff
73
stratum/algos/SWIFFTX/SWIFFTX.h
Normal file
73
stratum/algos/SWIFFTX/SWIFFTX.h
Normal file
|
@ -0,0 +1,73 @@
|
|||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SWIFFTX ANSI C OPTIMIZED 32BIT IMPLEMENTATION FOR NIST SHA-3 COMPETITION
|
||||
//
|
||||
// SWIFFTX.h
|
||||
//
|
||||
// October 2008
|
||||
//
|
||||
// This file is the exact copy from the reference implementation.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef __SWIFFTX__
|
||||
#define __SWIFFTX__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif
|
||||
|
||||
// See the remarks concerning compatibility issues inside stdint.h.
|
||||
#include "stdint.h"
|
||||
#include "stdbool.h"
|
||||
|
||||
// The size of SWIFFTX input in bytes.
|
||||
#define SWIFFTX_INPUT_BLOCK_SIZE 256
|
||||
|
||||
// The size of output block in bytes. The compression function of SWIFFT outputs a block of
|
||||
// this size (i.e., this is the size of the resulting hash value).
|
||||
#define SWIFFTX_OUTPUT_BLOCK_SIZE 65
|
||||
|
||||
// Computes the result of a single SWIFFT operation.
|
||||
// This is the simple implementation, where our main concern is to show our design principles.
|
||||
// It is made more efficient in the optimized version, by using FFT instead of DFT, and
|
||||
// through other speed-up techniques.
|
||||
//
|
||||
// Parameters:
|
||||
// - input: the input string. Consists of 8*m input bytes, where each octet passes the DFT
|
||||
// processing.
|
||||
// - m: the length of the input in bytes.
|
||||
// - output: the resulting hash value of SWIFFT, of size 65 bytes (520 bit). This is the
|
||||
// result of summing the dot products of the DFTS with the A's after applying the base
|
||||
// change transformation
|
||||
// - A: the A's coefficients to work with (since every SWIFFT in SWIFFTX uses different As).
|
||||
// A single application of SWIFFT uses 64*m A's.
|
||||
void ComputeSingleSWIFFT(unsigned char *input, unsigned short m,
|
||||
unsigned char output[SWIFFTX_OUTPUT_BLOCK_SIZE],
|
||||
const swift_int16_t *a);
|
||||
|
||||
// Computes the result of a single SWIFFTX operation.
|
||||
// NOTE: for simplicity we use 'ComputeSingleSWIFFT()' as a subroutine. This is only to show
|
||||
// the design idea. In the optimized versions we don't do this for efficiency concerns, since
|
||||
// there we compute the first part (which doesn't involve the A coefficients) only once for all
|
||||
// of the 3 invocations of SWIFFT. This enables us to introduce a significant speedup.
|
||||
//
|
||||
// Parameters:
|
||||
// - input: the input input of 256 bytes (2048 bit).
|
||||
// - output: the resulting hash value of SWIFFT, of size 64 bytes (512 bit).
|
||||
// - doSMooth: if true, a final smoothing stage is performed and the output is of size 512 bits.
|
||||
//
|
||||
// Returns:
|
||||
// - Success value.
|
||||
void ComputeSingleSWIFFTX(unsigned char input[SWIFFTX_INPUT_BLOCK_SIZE],
|
||||
unsigned char output[SWIFFTX_OUTPUT_BLOCK_SIZE],
|
||||
bool doSmooth);
|
||||
|
||||
// Calculates the powers of OMEGA and generates the bit reversal permutation.
|
||||
// You must call this function before doing SWIFFT/X, otherwise you will get zeroes everywhere.
|
||||
void InitializeSWIFFTX();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __SWIFFTX__
|
39
stratum/algos/SWIFFTX/inttypes.h
Normal file
39
stratum/algos/SWIFFTX/inttypes.h
Normal file
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
inttypes.h
|
||||
|
||||
Contributors:
|
||||
Created by Marek Michalkiewicz <marekm@linux.org.pl>
|
||||
|
||||
THIS SOFTWARE IS NOT COPYRIGHTED
|
||||
|
||||
This source code is offered for use in the public domain. You may
|
||||
use, modify or distribute it freely.
|
||||
|
||||
This code is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
|
||||
DISCLAIMED. This includes but is not limited to warranties of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#ifndef __INTTYPES_H_
|
||||
#define __INTTYPES_H_
|
||||
|
||||
/* Use [u]intN_t if you need exactly N bits.
|
||||
XXX - doesn't handle the -mint8 option. */
|
||||
|
||||
typedef signed char swift_int8_t;
|
||||
typedef unsigned char swift_uint8_t;
|
||||
|
||||
typedef int swift_int16_t;
|
||||
typedef unsigned int swift_uint16_t;
|
||||
|
||||
typedef long swift_int32_t;
|
||||
typedef unsigned long swift_uint32_t;
|
||||
|
||||
typedef long long swift_int64_t;
|
||||
typedef unsigned long long swift_uint64_t;
|
||||
|
||||
//typedef swift_int16_t intptr_t;
|
||||
//typedef swift_uint16_t uintptr_t;
|
||||
|
||||
#endif
|
46
stratum/algos/SWIFFTX/stdbool.h
Normal file
46
stratum/algos/SWIFFTX/stdbool.h
Normal file
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Copyright (c) 2000 Jeroen Ruigrok van der Werven <asmodai@FreeBSD.org>
|
||||
* 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.
|
||||
*
|
||||
* $FreeBSD: src/include/stdbool.h,v 1.6 2002/08/16 07:33:14 alfred Exp $
|
||||
*/
|
||||
|
||||
#ifndef _STDBOOL_H_
|
||||
#define _STDBOOL_H_
|
||||
|
||||
#define __bool_true_false_are_defined 1
|
||||
|
||||
#ifndef __cplusplus
|
||||
|
||||
#define false 0
|
||||
#define true 1
|
||||
|
||||
#define bool _Bool
|
||||
#if __STDC_VERSION__ < 199901L && __GNUC__ < 3
|
||||
typedef int _Bool;
|
||||
#endif
|
||||
|
||||
#endif /* !__cplusplus */
|
||||
|
||||
#endif /* !_STDBOOL_H_ */
|
54
stratum/algos/SWIFFTX/stdint.h
Normal file
54
stratum/algos/SWIFFTX/stdint.h
Normal file
|
@ -0,0 +1,54 @@
|
|||
#ifndef _SWIFFT_STDINT_H
|
||||
#define _SWIFFT_STDINT_H
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// A note from SWIFFTX implementers:
|
||||
//
|
||||
// Although the submission was targeted for Microsoft Visual Studio 2005 compiler, we strived
|
||||
// to make the code as portable as possible. This is why we preferred to use the types defined
|
||||
// here, instead of Microsoft-specific types. We compiled the code with gcc to make this sure.
|
||||
// However, we couldn't use this header as is, due to VS2005 compiler objections. This is why
|
||||
// we commented out certain defines and clearly marked it.
|
||||
// To compile our code on gcc you may define SYS_STDINT.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef SYS_STDINT
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#else
|
||||
|
||||
#include "inttypes.h"
|
||||
// The following was commented out by SWIFFTX implementers:
|
||||
// __BEGIN_DECLS
|
||||
|
||||
typedef swift_int8_t swifftx_int_least8_t;
|
||||
typedef swift_int16_t swifftx_int_least16_t;
|
||||
typedef swift_int32_t swifftx_int_least32_t;
|
||||
typedef swift_uint8_t swifftx_uint_least8_t;
|
||||
typedef swift_uint16_t swifftx_uint_least16_t;
|
||||
typedef swift_uint32_t swifftx_uint_least32_t;
|
||||
|
||||
#ifndef __STRICT_ANSI__
|
||||
typedef swift_int64_t swifftx_int_least64_t;
|
||||
typedef swift_uint64_t swifftx_uint_least64_t;
|
||||
#endif
|
||||
|
||||
/*typedef signed char int_fast8_t;
|
||||
typedef signed long int int_fast16_t;
|
||||
typedef signed long int int_fast32_t;
|
||||
typedef signed long long int int_fast64_t;
|
||||
|
||||
typedef unsigned char uint_fast8_t;
|
||||
typedef unsigned long int uint_fast16_t;
|
||||
typedef unsigned long int uint_fast32_t;
|
||||
typedef unsigned long long int uint_fast64_t;*/
|
||||
|
||||
// The following was commented out by SWIFFTX implementers:
|
||||
// #include <endian.h>
|
||||
// __END_DECLS
|
||||
#endif
|
||||
|
||||
#endif
|
260
stratum/algos/a5a.c
Normal file
260
stratum/algos/a5a.c
Normal file
|
@ -0,0 +1,260 @@
|
|||
#include <float.h>
|
||||
#include <math.h>
|
||||
#include <gmp.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "a5amath.h"
|
||||
|
||||
#include "../sha3/sph_sha2.h"
|
||||
#include "../sha3/sph_keccak.h"
|
||||
#include "../sha3/sph_whirlpool.h"
|
||||
#include "../sha3/sph_ripemd.h"
|
||||
|
||||
static void mpz_set_uint256(mpz_t r, uint8_t *u)
|
||||
{
|
||||
mpz_import(r, 32 / sizeof(unsigned long), -1, sizeof(unsigned long), -1, 0, u);
|
||||
}
|
||||
|
||||
static void mpz_get_uint256(mpz_t r, uint8_t *u)
|
||||
{
|
||||
u=0;
|
||||
mpz_export(u, 0, -1, sizeof(unsigned long), -1, 0, r);
|
||||
}
|
||||
|
||||
static void mpz_set_uint512(mpz_t r, uint8_t *u)
|
||||
{
|
||||
mpz_import(r, 64 / sizeof(unsigned long), -1, sizeof(unsigned long), -1, 0, u);
|
||||
}
|
||||
|
||||
static void set_one_if_zero(uint8_t *hash512) {
|
||||
int i;
|
||||
for (i = 0; i < 32; i++) {
|
||||
if (hash512[i] != 0) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
hash512[0] = 1;
|
||||
}
|
||||
|
||||
#define BITS_PER_DIGIT 3.32192809488736234787
|
||||
//#define EPS (std::numeric_limits<double>::epsilon())
|
||||
#define EPS (DBL_EPSILON)
|
||||
|
||||
#define Na5a 5
|
||||
#define SW_DIVS 5
|
||||
//#define SW_MAX 1000
|
||||
|
||||
void a5a_hash(const char* input, char* output, uint32_t len)
|
||||
{
|
||||
unsigned int nnNonce;
|
||||
uint32_t pdata[32];
|
||||
memcpy(pdata, input, 80);
|
||||
// memcpy(&nnNonce, input+76, 4);
|
||||
|
||||
int i, j, bytes, nnNonce2;
|
||||
nnNonce2 = (int)(pdata[19]/2);
|
||||
size_t sz = 80;
|
||||
uint8_t bhash[5][64];
|
||||
uint32_t hash[6];
|
||||
memset(bhash, 0, 5 * 64);
|
||||
|
||||
sph_sha256_context ctx_final_sha256;
|
||||
|
||||
sph_sha256_context ctx_sha256;
|
||||
sph_sha512_context ctx_sha512;
|
||||
sph_keccak512_context ctx_keccak;
|
||||
sph_whirlpool_context ctx_whirlpool;
|
||||
sph_ripemd160_context ctx_ripemd;
|
||||
|
||||
sph_sha256_init(&ctx_sha256);
|
||||
// ZSHA256;
|
||||
sph_sha256 (&ctx_sha256, input, sz);
|
||||
sph_sha256_close(&ctx_sha256, (void*)(bhash[0]));
|
||||
|
||||
sph_sha512_init(&ctx_sha512);
|
||||
// ZSHA512;
|
||||
sph_sha512 (&ctx_sha512, input, sz);
|
||||
sph_sha512_close(&ctx_sha512, (void*)(bhash[1]));
|
||||
|
||||
sph_keccak512_init(&ctx_keccak);
|
||||
// ZKECCAK;
|
||||
sph_keccak512 (&ctx_keccak, input, sz);
|
||||
sph_keccak512_close(&ctx_keccak, (void*)(bhash[2]));
|
||||
|
||||
sph_whirlpool_init(&ctx_whirlpool);
|
||||
// ZWHIRLPOOL;
|
||||
sph_whirlpool (&ctx_whirlpool, input, sz);
|
||||
sph_whirlpool_close(&ctx_whirlpool, (void*)(bhash[3]));
|
||||
|
||||
sph_ripemd160_init(&ctx_ripemd);
|
||||
// ZRIPEMD;
|
||||
sph_ripemd160 (&ctx_ripemd, input, sz);
|
||||
sph_ripemd160_close(&ctx_ripemd, (void*)(bhash[4]));
|
||||
|
||||
// printf("%s\n", hash[4].GetHex().c_str());
|
||||
|
||||
mpz_t bns[6];
|
||||
for(i=0; i < 6; i++){
|
||||
mpz_init(bns[i]);
|
||||
}
|
||||
//Take care of zeros and load gmp
|
||||
for(i=0; i < 5; i++){
|
||||
set_one_if_zero(bhash[i]);
|
||||
mpz_set_uint512(bns[i],bhash[i]);
|
||||
}
|
||||
|
||||
mpz_set_ui(bns[5],0);
|
||||
for(i=0; i < 5; i++)
|
||||
mpz_add(bns[5], bns[5], bns[i]);
|
||||
|
||||
mpz_t product;
|
||||
mpz_init(product);
|
||||
mpz_set_ui(product,1);
|
||||
// mpz_pow_ui(bns[5], bns[5], 2);
|
||||
for(i=0; i < 6; i++){
|
||||
mpz_mul(product,product,bns[i]);
|
||||
}
|
||||
mpz_pow_ui(product, product, 2);
|
||||
|
||||
bytes = mpz_sizeinbase(product, 256);
|
||||
// printf("a5a data space: %iB\n", bytes);
|
||||
char *data = (char*)malloc(bytes);
|
||||
mpz_export(data, NULL, -1, 1, 0, 0, product);
|
||||
|
||||
sph_sha256_init(&ctx_final_sha256);
|
||||
// ZSHA256;
|
||||
sph_sha256 (&ctx_final_sha256, data, bytes);
|
||||
sph_sha256_close(&ctx_final_sha256, (void*)(hash));
|
||||
free(data);
|
||||
|
||||
int digits=(int)((sqrt((double)(nnNonce2))*(1.+EPS))/9000+75);
|
||||
// int iterations=(int)((sqrt((double)(nnNonce2))+EPS)/500+350); // <= 500
|
||||
// int digits=100;
|
||||
int iterations=20; // <= 500
|
||||
mpf_set_default_prec((long int)(digits*BITS_PER_DIGIT+16));
|
||||
|
||||
mpz_t a5api;
|
||||
mpz_t a5asw;
|
||||
mpf_t a5afpi;
|
||||
mpf_t mpa1, mpb1, mpt1, mpp1;
|
||||
mpf_t mpa2, mpb2, mpt2, mpp2;
|
||||
mpf_t mpsft;
|
||||
|
||||
mpz_init(a5api);
|
||||
mpz_init(a5asw);
|
||||
mpf_init(a5afpi);
|
||||
mpf_init(mpsft);
|
||||
mpf_init(mpa1);
|
||||
mpf_init(mpb1);
|
||||
mpf_init(mpt1);
|
||||
mpf_init(mpp1);
|
||||
|
||||
mpf_init(mpa2);
|
||||
mpf_init(mpb2);
|
||||
mpf_init(mpt2);
|
||||
mpf_init(mpp2);
|
||||
|
||||
uint32_t usw_;
|
||||
usw_ = sw_(nnNonce2, SW_DIVS);
|
||||
if (usw_ < 1) usw_ = 1;
|
||||
// if(fDebuga5a) printf("usw_: %d\n", usw_);
|
||||
mpz_set_ui(a5asw, usw_);
|
||||
uint32_t mpzscale=mpz_size(a5asw);
|
||||
for(i=0; i < Na5a; i++)
|
||||
{
|
||||
if (mpzscale > 1000) {
|
||||
mpzscale = 1000;
|
||||
}
|
||||
else if (mpzscale < 1) {
|
||||
mpzscale = 1;
|
||||
}
|
||||
// if(fDebuga5a) printf("mpzscale: %d\n", mpzscale);
|
||||
|
||||
mpf_set_ui(mpa1, 1);
|
||||
mpf_set_ui(mpb1, 2);
|
||||
mpf_set_d(mpt1, 0.25*mpzscale);
|
||||
mpf_set_ui(mpp1, 1);
|
||||
mpf_sqrt(mpb1, mpb1);
|
||||
mpf_ui_div(mpb1, 1, mpb1);
|
||||
mpf_set_ui(mpsft, 10);
|
||||
|
||||
for(j=0; j <= iterations; j++)
|
||||
{
|
||||
mpf_add(mpa2, mpa1, mpb1);
|
||||
mpf_div_ui(mpa2, mpa2, 2);
|
||||
mpf_mul(mpb2, mpa1, mpb1);
|
||||
mpf_abs(mpb2, mpb2);
|
||||
mpf_sqrt(mpb2, mpb2);
|
||||
mpf_sub(mpt2, mpa1, mpa2);
|
||||
mpf_abs(mpt2, mpt2);
|
||||
mpf_sqrt(mpt2, mpt2);
|
||||
mpf_mul(mpt2, mpt2, mpp1);
|
||||
mpf_sub(mpt2, mpt1, mpt2);
|
||||
mpf_mul_ui(mpp2, mpp1, 2);
|
||||
mpf_swap(mpa1, mpa2);
|
||||
mpf_swap(mpb1, mpb2);
|
||||
mpf_swap(mpt1, mpt2);
|
||||
mpf_swap(mpp1, mpp2);
|
||||
}
|
||||
mpf_add(a5afpi, mpa1, mpb1);
|
||||
mpf_pow_ui(a5afpi, a5afpi, 2);
|
||||
mpf_div_ui(a5afpi, a5afpi, 4);
|
||||
mpf_abs(mpt1, mpt1);
|
||||
mpf_div(a5afpi, a5afpi, mpt1);
|
||||
|
||||
// mpf_out_str(stdout, 10, digits+2, a5afpi);
|
||||
|
||||
mpf_pow_ui(mpsft, mpsft, digits/2);
|
||||
mpf_mul(a5afpi, a5afpi, mpsft);
|
||||
|
||||
mpz_set_f(a5api, a5afpi);
|
||||
|
||||
//mpz_set_ui(a5api,1);
|
||||
|
||||
mpz_add(product,product,a5api);
|
||||
mpz_add(product,product,a5asw);
|
||||
|
||||
mpz_set_uint256(bns[0], (void*)(hash));
|
||||
mpz_add(bns[5], bns[5], bns[0]);
|
||||
|
||||
mpz_mul(product,product,bns[5]);
|
||||
mpz_cdiv_q (product, product, bns[0]);
|
||||
if (mpz_sgn(product) <= 0) mpz_set_ui(product,1);
|
||||
|
||||
bytes = mpz_sizeinbase(product, 256);
|
||||
mpzscale=bytes;
|
||||
// printf("a5a data space: %iB\n", bytes);
|
||||
char *bdata = (char*)malloc(bytes);
|
||||
mpz_export(bdata, NULL, -1, 1, 0, 0, product);
|
||||
|
||||
sph_sha256_init(&ctx_final_sha256);
|
||||
// ZSHA256;
|
||||
sph_sha256 (&ctx_final_sha256, bdata, bytes);
|
||||
sph_sha256_close(&ctx_final_sha256, (void*)(hash));
|
||||
free(bdata);
|
||||
}
|
||||
//Free the memory
|
||||
for(i=0; i < 6; i++){
|
||||
mpz_clear(bns[i]);
|
||||
}
|
||||
// mpz_clear(dSpectralWeight);
|
||||
mpz_clear(product);
|
||||
|
||||
mpz_clear(a5api);
|
||||
mpz_clear(a5asw);
|
||||
mpf_clear(a5afpi);
|
||||
mpf_clear(mpsft);
|
||||
mpf_clear(mpa1);
|
||||
mpf_clear(mpb1);
|
||||
mpf_clear(mpt1);
|
||||
mpf_clear(mpp1);
|
||||
|
||||
mpf_clear(mpa2);
|
||||
mpf_clear(mpb2);
|
||||
mpf_clear(mpt2);
|
||||
mpf_clear(mpp2);
|
||||
|
||||
memcpy(output, hash, 32);
|
||||
}
|
14
stratum/algos/a5a.h
Normal file
14
stratum/algos/a5a.h
Normal file
|
@ -0,0 +1,14 @@
|
|||
#ifndef SCRYPT_H
|
||||
#define SCRYPT_H
|
||||
#include <stdint.h>
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void a5a_hash(const char* input, char* output, uint32_t len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
116
stratum/algos/a5amath.c
Normal file
116
stratum/algos/a5amath.c
Normal file
|
@ -0,0 +1,116 @@
|
|||
// Copyright (c) 2014 The a5a developers
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <float.h>
|
||||
#include <limits.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
//#include <gmpxx.h>
|
||||
#include "a5amath.h"
|
||||
|
||||
//#define EPS1 (std::numeric_limits<double>::epsilon())
|
||||
#define EPS1 (DBL_EPSILON)
|
||||
#define EPS2 3.0e-11
|
||||
|
||||
double exp_n(double xt)
|
||||
{
|
||||
double p1 = -700.0, p3 = -0.8e-8, p4 = 0.8e-8, p6 = 700.0;
|
||||
if(xt < p1)
|
||||
return 0;
|
||||
else if(xt > p6)
|
||||
return 1e200;
|
||||
else if(xt > p3 && xt < p4)
|
||||
return (1.0 + xt);
|
||||
else
|
||||
return exp(xt);
|
||||
}
|
||||
|
||||
// 1 / (1 + exp(x1-x2))
|
||||
double exp_n2(double x1, double x2)
|
||||
{
|
||||
double p1 = -700., p2 = -37., p3 = -0.8e-8, p4 = 0.8e-8, p5 = 37., p6 = 700.;
|
||||
double xt = x1 - x2;
|
||||
if (xt < p1+1.e-200)
|
||||
return 1.;
|
||||
else if (xt > p1 && xt < p2 + 1.e-200)
|
||||
return ( 1. - exp(xt) );
|
||||
else if (xt > p2 && xt < p3 + 1.e-200)
|
||||
return ( 1. / (1. + exp(xt)) );
|
||||
else if (xt > p3 && xt < p4)
|
||||
return ( 1. / (2. + xt) );
|
||||
else if (xt > p4 - 1.e-200 && xt < p5)
|
||||
return ( exp(-xt) / (1. + exp(-xt)) );
|
||||
else if (xt > p5 - 1.e-200 && xt < p6)
|
||||
return ( exp(-xt) );
|
||||
else if (xt > p6 - 1.e-200)
|
||||
return 0.;
|
||||
}
|
||||
|
||||
void gauleg(double x1, double x2, double x[], double w[], int n)
|
||||
{
|
||||
int m,j,i;
|
||||
double z1, z, xm, xl, pp, p3, p2, p1;
|
||||
m=(n+1)/2;
|
||||
xm=0.5*(x2+x1);
|
||||
xl=0.5*(x2-x1);
|
||||
for (i=1;i<=m;i++) {
|
||||
z=cos(3.141592654*(i-0.25)/(n+0.5));
|
||||
do {
|
||||
p1=1.0;
|
||||
p2=0.0;
|
||||
for (j=1;j<=n;j++) {
|
||||
p3=p2;
|
||||
p2=p1;
|
||||
p1=((2.0*j-1.0)*z*p2-(j-1.0)*p3)/j;
|
||||
}
|
||||
pp=n*(z*p1-p2)/(z*z-1.0);
|
||||
z1=z;
|
||||
z=z1-p1/pp;
|
||||
} while (fabs(z-z1) > EPS2);
|
||||
x[i]=xm-xl*z;
|
||||
x[n+1-i]=xm+xl*z;
|
||||
w[i]=2.0*xl/((1.0-z*z)*pp*pp);
|
||||
w[n+1-i]=w[i];
|
||||
}
|
||||
}
|
||||
|
||||
double GaussianQuad_N(double func(const double), const double a2, const double b2, int NptGQ)
|
||||
{
|
||||
double s=0.0;
|
||||
double x[NptGQ], w[NptGQ];
|
||||
int j;
|
||||
// double dh=(b2-a2)/double(divs);
|
||||
gauleg(a2, b2, x, w, NptGQ);
|
||||
for (j=1; j<=NptGQ; j++) {
|
||||
s += w[j]*func(x[j]);
|
||||
}
|
||||
/*
|
||||
for (i=1; i<=divs; i++)
|
||||
{
|
||||
a0 = a2 + (i-1)*dh;
|
||||
b0 = a0 + dh;
|
||||
gauleg(a0, b0, x, w, NptGQ);
|
||||
for (j=1; j<=NptGQ; j++)
|
||||
{
|
||||
s += w[j]*func(x[j]);
|
||||
}
|
||||
}
|
||||
*/
|
||||
return s;
|
||||
}
|
||||
|
||||
double swit_(double wvnmb)
|
||||
{
|
||||
return pow( (5.55243*(exp_n(-0.3*wvnmb/15.762) - exp_n(-0.6*wvnmb/15.762)))*wvnmb, 0.5)
|
||||
/ 1034.66 * pow(sin(wvnmb/65.), 2.);
|
||||
}
|
||||
|
||||
uint32_t sw_(int nnounce, int divs)
|
||||
{
|
||||
double wmax = ((sqrt((double)(nnounce))*(1.+EPS1))/450+100);
|
||||
return ((uint32_t)(GaussianQuad_N(swit_, 0., wmax, divs)*(1.+EPS1)*1.e6));
|
||||
}
|
16
stratum/algos/a5amath.h
Normal file
16
stratum/algos/a5amath.h
Normal file
|
@ -0,0 +1,16 @@
|
|||
// Copyright (c) 2014 The a5a developers
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
#ifndef a5a_MATH_H
|
||||
#define a5a_MATH_H
|
||||
|
||||
double exp_n(double xt);
|
||||
double exp_n2(double x1, double x2);
|
||||
void gauleg(double x1, double x2, double x[], double w[], int n);
|
||||
double GaussianQuad_N(double func(const double), const double a2, const double b2, int NptGQ);
|
||||
double swit_(double wvnmb);
|
||||
uint32_t sw_(int nnounce, int divs);
|
||||
|
||||
|
||||
|
||||
#endif
|
162
stratum/algos/aergo.c
Normal file
162
stratum/algos/aergo.c
Normal file
|
@ -0,0 +1,162 @@
|
|||
#include "aergo.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <sha3/sph_blake.h>
|
||||
#include <sha3/sph_bmw.h>
|
||||
#include <sha3/sph_groestl.h>
|
||||
#include <sha3/sph_jh.h>
|
||||
#include <sha3/sph_keccak.h>
|
||||
#include <sha3/sph_skein.h>
|
||||
#include <sha3/sph_luffa.h>
|
||||
#include <sha3/sph_cubehash.h>
|
||||
#include <sha3/sph_shavite.h>
|
||||
#include <sha3/sph_simd.h>
|
||||
#include <sha3/sph_echo.h>
|
||||
#include <sha3/sph_hamsi.h>
|
||||
#include <sha3/sph_fugue.h>
|
||||
#include <sha3/sph_shabal.h>
|
||||
#include <sha3/sph_whirlpool.h>
|
||||
#include <sha3/sph_haval.h>
|
||||
#include "gost.h"
|
||||
|
||||
#include "common.h"
|
||||
|
||||
void aergo_hash(const char* input, char* output, uint32_t len)
|
||||
{
|
||||
uint32_t hash[16];
|
||||
|
||||
sph_blake512_context ctx_blake;
|
||||
sph_bmw512_context ctx_bmw;
|
||||
sph_groestl512_context ctx_groestl;
|
||||
sph_jh512_context ctx_jh;
|
||||
sph_keccak512_context ctx_keccak;
|
||||
sph_skein512_context ctx_skein;
|
||||
sph_luffa512_context ctx_luffa;
|
||||
sph_cubehash512_context ctx_cubehash;
|
||||
sph_shavite512_context ctx_shavite;
|
||||
sph_simd512_context ctx_simd;
|
||||
sph_echo512_context ctx_echo;
|
||||
sph_hamsi512_context ctx_hamsi;
|
||||
sph_fugue512_context ctx_fugue;
|
||||
sph_shabal512_context ctx_shabal;
|
||||
sph_gost512_context ctx_gost;
|
||||
sph_whirlpool_context ctx_whirlpool;
|
||||
sph_haval256_5_context ctx_haval;
|
||||
|
||||
sph_echo512_init(&ctx_echo);
|
||||
sph_echo512(&ctx_echo, input, len);
|
||||
sph_echo512_close(&ctx_echo, hash);
|
||||
|
||||
sph_simd512_init(&ctx_simd);
|
||||
sph_simd512(&ctx_simd, hash, 64);
|
||||
sph_simd512_close(&ctx_simd, hash);
|
||||
|
||||
sph_blake512_init(&ctx_blake);
|
||||
sph_blake512(&ctx_blake, hash, 64);
|
||||
sph_blake512_close(&ctx_blake, hash);
|
||||
|
||||
sph_bmw512_init(&ctx_bmw);
|
||||
sph_bmw512(&ctx_bmw, hash, 64);
|
||||
sph_bmw512_close(&ctx_bmw, hash);
|
||||
|
||||
sph_whirlpool_init(&ctx_whirlpool);
|
||||
sph_whirlpool(&ctx_whirlpool, hash, 64);
|
||||
sph_whirlpool_close(&ctx_whirlpool, hash);
|
||||
|
||||
sph_groestl512_init(&ctx_groestl);
|
||||
sph_groestl512(&ctx_groestl, hash, 64);
|
||||
sph_groestl512_close(&ctx_groestl, hash);
|
||||
|
||||
sph_gost512_init(&ctx_gost);
|
||||
sph_gost512(&ctx_gost, hash, 64);
|
||||
sph_gost512_close(&ctx_gost, hash);
|
||||
|
||||
sph_skein512_init(&ctx_skein);
|
||||
sph_skein512(&ctx_skein, hash, 64);
|
||||
sph_skein512_close(&ctx_skein, hash);
|
||||
|
||||
sph_bmw512_init(&ctx_bmw);
|
||||
sph_bmw512(&ctx_bmw, hash, 64);
|
||||
sph_bmw512_close(&ctx_bmw, hash);
|
||||
|
||||
sph_jh512_init(&ctx_jh);
|
||||
sph_jh512(&ctx_jh, hash, 64);
|
||||
sph_jh512_close(&ctx_jh, hash);
|
||||
|
||||
sph_luffa512_init(&ctx_luffa);
|
||||
sph_luffa512(&ctx_luffa, hash, 64);
|
||||
sph_luffa512_close(&ctx_luffa, hash);
|
||||
|
||||
sph_keccak512_init(&ctx_keccak);
|
||||
sph_keccak512(&ctx_keccak, hash, 64);
|
||||
sph_keccak512_close(&ctx_keccak, hash);
|
||||
|
||||
sph_gost512_init(&ctx_gost);
|
||||
sph_gost512(&ctx_gost, hash, 64);
|
||||
sph_gost512_close(&ctx_gost, hash);
|
||||
|
||||
sph_cubehash512_init(&ctx_cubehash);
|
||||
sph_cubehash512(&ctx_cubehash, hash, 64);
|
||||
sph_cubehash512_close(&ctx_cubehash, hash);
|
||||
|
||||
sph_echo512_init(&ctx_echo);
|
||||
sph_echo512(&ctx_echo, hash, 64);
|
||||
sph_echo512_close(&ctx_echo, hash);
|
||||
|
||||
sph_simd512_init(&ctx_simd);
|
||||
sph_simd512(&ctx_simd, hash, 64);
|
||||
sph_simd512_close(&ctx_simd, hash);
|
||||
|
||||
sph_hamsi512_init(&ctx_hamsi);
|
||||
sph_hamsi512(&ctx_hamsi, hash, 64);
|
||||
sph_hamsi512_close(&ctx_hamsi, hash);
|
||||
|
||||
sph_fugue512_init(&ctx_fugue);
|
||||
sph_fugue512(&ctx_fugue, hash, 64);
|
||||
sph_fugue512_close(&ctx_fugue, hash);
|
||||
|
||||
sph_shavite512_init(&ctx_shavite);
|
||||
sph_shavite512(&ctx_shavite, hash, 64);
|
||||
sph_shavite512_close(&ctx_shavite, hash);
|
||||
|
||||
sph_shabal512_init(&ctx_shabal);
|
||||
sph_shabal512(&ctx_shabal, hash, 64);
|
||||
sph_shabal512_close(&ctx_shabal, hash);
|
||||
|
||||
sph_haval256_5_init(&ctx_haval);
|
||||
sph_haval256_5(&ctx_haval,(const void*) hash, 64);
|
||||
sph_haval256_5_close(&ctx_haval, hash);
|
||||
|
||||
sph_shavite512_init(&ctx_shavite);
|
||||
sph_shavite512(&ctx_shavite, hash, 64);
|
||||
sph_shavite512_close(&ctx_shavite, hash);
|
||||
|
||||
sph_gost512_init(&ctx_gost);
|
||||
sph_gost512(&ctx_gost, hash, 64);
|
||||
sph_gost512_close(&ctx_gost, hash);
|
||||
|
||||
sph_echo512_init(&ctx_echo);
|
||||
sph_echo512(&ctx_echo, hash, 64);
|
||||
sph_echo512_close(&ctx_echo, hash);
|
||||
|
||||
sph_blake512_init(&ctx_blake);
|
||||
sph_blake512(&ctx_blake, hash, 64);
|
||||
sph_blake512_close(&ctx_blake, hash);
|
||||
|
||||
sph_jh512_init(&ctx_jh);
|
||||
sph_jh512(&ctx_jh, hash, 64);
|
||||
sph_jh512_close(&ctx_jh, hash);
|
||||
|
||||
sph_cubehash512_init(&ctx_cubehash);
|
||||
sph_cubehash512(&ctx_cubehash, hash, 64);
|
||||
sph_cubehash512_close(&ctx_cubehash, hash);
|
||||
|
||||
sph_simd512_init(&ctx_simd);
|
||||
sph_simd512(&ctx_simd, hash, 64);
|
||||
sph_simd512_close(&ctx_simd, hash);
|
||||
|
||||
memcpy(output, hash, 32);
|
||||
}
|
17
stratum/algos/aergo.h
Normal file
17
stratum/algos/aergo.h
Normal file
|
@ -0,0 +1,17 @@
|
|||
|
||||
#ifndef AERGO_H
|
||||
#define AERGO_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
void aergo_hash(const char* input, char* output, uint32_t len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
46
stratum/algos/allium.c
Normal file
46
stratum/algos/allium.c
Normal file
|
@ -0,0 +1,46 @@
|
|||
#include <memory.h>
|
||||
|
||||
#include "sha3/sph_blake.h"
|
||||
#include "sha3/sph_groestl.h"
|
||||
#include "sha3/sph_skein.h"
|
||||
#include "sha3/sph_keccak.h"
|
||||
#include "sha3/sph_cubehash.h"
|
||||
|
||||
#include "Lyra2.h"
|
||||
|
||||
void allium_hash(const char* input, char* output, uint32_t len)
|
||||
{
|
||||
uint32_t hashA[8], hashB[8];
|
||||
|
||||
sph_blake256_context ctx_blake;
|
||||
sph_keccak256_context ctx_keccak;
|
||||
sph_cubehash512_context ctx_cubehash;
|
||||
sph_skein256_context ctx_skein;
|
||||
sph_groestl256_context ctx_groestl;
|
||||
|
||||
sph_blake256_init(&ctx_blake);
|
||||
sph_blake256(&ctx_blake, input, 80);
|
||||
sph_blake256_close(&ctx_blake, hashA);
|
||||
|
||||
sph_keccak256_init(&ctx_keccak);
|
||||
sph_keccak256(&ctx_keccak, hashA, 32);
|
||||
sph_keccak256_close(&ctx_keccak, hashB);
|
||||
|
||||
LYRA2(hashA, 32, hashB, 32, hashB, 32, 1, 8, 8);
|
||||
|
||||
sph_cubehash256_init(&ctx_cubehash);
|
||||
sph_cubehash256(&ctx_cubehash, hashA, 32);
|
||||
sph_cubehash256_close(&ctx_cubehash, hashB);
|
||||
|
||||
LYRA2(hashA, 32, hashB, 32, hashB, 32, 1, 8, 8);
|
||||
|
||||
sph_skein256_init(&ctx_skein);
|
||||
sph_skein256(&ctx_skein, hashA, 32);
|
||||
sph_skein256_close(&ctx_skein, hashB);
|
||||
|
||||
sph_groestl256_init(&ctx_groestl);
|
||||
sph_groestl256(&ctx_groestl, hashB, 32);
|
||||
sph_groestl256_close(&ctx_groestl, hashA);
|
||||
|
||||
memcpy(output, hashA, 32);
|
||||
}
|
16
stratum/algos/allium.h
Normal file
16
stratum/algos/allium.h
Normal file
|
@ -0,0 +1,16 @@
|
|||
#ifndef ALLIUM_H
|
||||
#define ALLIUM_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
void allium_hash(const char* input, char* output, uint32_t len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,279 +1,378 @@
|
|||
/*
|
||||
* Argon2 source code package
|
||||
* Argon2 reference source code package - reference C implementations
|
||||
*
|
||||
* Written by Daniel Dinu and Dmitry Khovratovich, 2015
|
||||
* Copyright 2015
|
||||
* Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
|
||||
*
|
||||
* This work is licensed under a Creative Commons CC0 1.0 License/Waiver.
|
||||
* You may use this work under the terms of a Creative Commons CC0 1.0
|
||||
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
|
||||
* these licenses can be found at:
|
||||
*
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along
|
||||
* with
|
||||
* this software. If not, see
|
||||
* <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* You should have received a copy of both of these licenses along with this
|
||||
* software. If not, they may be obtained at the above URLs.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "argon2.h"
|
||||
#include "cores.h"
|
||||
#include "encoding.h"
|
||||
#include "core.h"
|
||||
|
||||
/* Error messages */
|
||||
static const char *Argon2_ErrorMessage[] = {
|
||||
/*{ARGON2_OK, */ "OK",
|
||||
/*},
|
||||
const char *argon2_type2string(argon2_type type, int uppercase) {
|
||||
switch (type) {
|
||||
case Argon2_d:
|
||||
return uppercase ? "Argon2d" : "argon2d";
|
||||
}
|
||||
|
||||
{ARGON2_OUTPUT_PTR_NULL, */ "Output pointer is NULL",
|
||||
/*},
|
||||
return NULL;
|
||||
}
|
||||
|
||||
{ARGON2_OUTPUT_TOO_SHORT, */ "Output is too short",
|
||||
/*},
|
||||
{ARGON2_OUTPUT_TOO_LONG, */ "Output is too long",
|
||||
/*},
|
||||
|
||||
{ARGON2_PWD_TOO_SHORT, */ "Password is too short",
|
||||
/*},
|
||||
{ARGON2_PWD_TOO_LONG, */ "Password is too long",
|
||||
/*},
|
||||
|
||||
{ARGON2_SALT_TOO_SHORT, */ "Salt is too short",
|
||||
/*},
|
||||
{ARGON2_SALT_TOO_LONG, */ "Salt is too long",
|
||||
/*},
|
||||
|
||||
{ARGON2_AD_TOO_SHORT, */ "Associated data is too short",
|
||||
/*},
|
||||
{ARGON2_AD_TOO_LONG, */ "Associated date is too long",
|
||||
/*},
|
||||
|
||||
{ARGON2_SECRET_TOO_SHORT, */ "Secret is too short",
|
||||
/*},
|
||||
{ARGON2_SECRET_TOO_LONG, */ "Secret is too long",
|
||||
/*},
|
||||
|
||||
{ARGON2_TIME_TOO_SMALL, */ "Time cost is too small",
|
||||
/*},
|
||||
{ARGON2_TIME_TOO_LARGE, */ "Time cost is too large",
|
||||
/*},
|
||||
|
||||
{ARGON2_MEMORY_TOO_LITTLE, */ "Memory cost is too small",
|
||||
/*},
|
||||
{ARGON2_MEMORY_TOO_MUCH, */ "Memory cost is too large",
|
||||
/*},
|
||||
|
||||
{ARGON2_LANES_TOO_FEW, */ "Too few lanes",
|
||||
/*},
|
||||
{ARGON2_LANES_TOO_MANY, */ "Too many lanes",
|
||||
/*},
|
||||
|
||||
{ARGON2_PWD_PTR_MISMATCH, */ "Password pointer is NULL, but password length is not 0",
|
||||
/*},
|
||||
{ARGON2_SALT_PTR_MISMATCH, */ "Salt pointer is NULL, but salt length is not 0",
|
||||
/*},
|
||||
{ARGON2_SECRET_PTR_MISMATCH, */ "Secret pointer is NULL, but secret length is not 0",
|
||||
/*},
|
||||
{ARGON2_AD_PTR_MISMATCH, */ "Associated data pointer is NULL, but ad length is not 0",
|
||||
/*},
|
||||
|
||||
{ARGON2_MEMORY_ALLOCATION_ERROR, */ "Memory allocation error",
|
||||
/*},
|
||||
|
||||
{ARGON2_FREE_MEMORY_CBK_NULL, */ "The free memory callback is NULL",
|
||||
/*},
|
||||
{ARGON2_ALLOCATE_MEMORY_CBK_NULL, */ "The allocate memory callback is NULL",
|
||||
/*},
|
||||
|
||||
{ARGON2_INCORRECT_PARAMETER, */ "Argon2_Context context is NULL",
|
||||
/*},
|
||||
{ARGON2_INCORRECT_TYPE, */ "There is no such version of Argon2",
|
||||
/*},
|
||||
|
||||
{ARGON2_OUT_PTR_MISMATCH, */ "Output pointer mismatch",
|
||||
/*},
|
||||
|
||||
{ARGON2_THREADS_TOO_FEW, */ "Not enough threads",
|
||||
/*},
|
||||
{ARGON2_THREADS_TOO_MANY, */ "Too many threads",
|
||||
/*},
|
||||
{ARGON2_MISSING_ARGS, */ "Missing arguments", /*},*/
|
||||
};
|
||||
|
||||
int argon2d(argon2_context *context) { return argon2_core(context, Argon2_d); }
|
||||
|
||||
int argon2i(argon2_context *context) { return argon2_core(context, Argon2_i); }
|
||||
|
||||
int verify_d(argon2_context *context, const char *hash) {
|
||||
int result;
|
||||
/*if (0 == context->outlen || NULL == hash) {
|
||||
return ARGON2_OUT_PTR_MISMATCH;
|
||||
}*/
|
||||
|
||||
result = argon2_core(context, Argon2_d);
|
||||
int argon2_ctx(argon2_context *context, argon2_type type) {
|
||||
/* 1. Validate all inputs */
|
||||
int result = validate_inputs(context);
|
||||
uint32_t memory_blocks, segment_length;
|
||||
argon2_instance_t instance;
|
||||
|
||||
if (ARGON2_OK != result) {
|
||||
return result;
|
||||
}
|
||||
|
||||
return 0 == memcmp(hash, context->out, 32);
|
||||
}
|
||||
|
||||
const char *error_message(int error_code) {
|
||||
enum {
|
||||
/* Make sure---at compile time---that the enum size matches the array
|
||||
size */
|
||||
ERROR_STRING_CHECK =
|
||||
1 /
|
||||
!!((sizeof(Argon2_ErrorMessage) / sizeof(Argon2_ErrorMessage[0])) ==
|
||||
ARGON2_ERROR_CODES_LENGTH)
|
||||
};
|
||||
if (error_code < ARGON2_ERROR_CODES_LENGTH) {
|
||||
return Argon2_ErrorMessage[(argon2_error_codes)error_code];
|
||||
if (Argon2_d != type) {
|
||||
return ARGON2_INCORRECT_TYPE;
|
||||
}
|
||||
return "Unknown error code.";
|
||||
}
|
||||
|
||||
/* encoding/decoding helpers */
|
||||
/* 2. Align memory size */
|
||||
/* Minimum memory_blocks = 8L blocks, where L is the number of lanes */
|
||||
memory_blocks = context->m_cost;
|
||||
|
||||
/*
|
||||
* Some macros for constant-time comparisons. These work over values in
|
||||
* the 0..255 range. Returned value is 0x00 on "false", 0xFF on "true".
|
||||
*/
|
||||
#define EQ(x, y) ((((0U - ((unsigned)(x) ^ (unsigned)(y))) >> 8) & 0xFF) ^ 0xFF)
|
||||
#define GT(x, y) ((((unsigned)(y) - (unsigned)(x)) >> 8) & 0xFF)
|
||||
#define GE(x, y) (GT(y, x) ^ 0xFF)
|
||||
#define LT(x, y) GT(y, x)
|
||||
#define LE(x, y) GE(y, x)
|
||||
|
||||
/*
|
||||
* Convert value x (0..63) to corresponding Base64 character.
|
||||
*/
|
||||
static int b64_byte_to_char(unsigned x) {
|
||||
return (LT(x, 26) & (x + 'A')) |
|
||||
(GE(x, 26) & LT(x, 52) & (x + ('a' - 26))) |
|
||||
(GE(x, 52) & LT(x, 62) & (x + ('0' - 52))) | (EQ(x, 62) & '+') |
|
||||
(EQ(x, 63) & '/');
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert some bytes to Base64. 'dst_len' is the length (in characters)
|
||||
* of the output buffer 'dst'; if that buffer is not large enough to
|
||||
* receive the result (including the terminating 0), then (size_t)-1
|
||||
* is returned. Otherwise, the zero-terminated Base64 string is written
|
||||
* in the buffer, and the output length (counted WITHOUT the terminating
|
||||
* zero) is returned.
|
||||
*/
|
||||
static size_t to_base64(char *dst, size_t dst_len, const void *src) {
|
||||
size_t olen;
|
||||
const unsigned char *buf;
|
||||
unsigned acc, acc_len;
|
||||
|
||||
olen = 43;
|
||||
/*switch (32 % 3) {
|
||||
case 2:
|
||||
olen++;*/
|
||||
/* fall through */
|
||||
/*case 1:
|
||||
olen += 2;
|
||||
break;
|
||||
}*/
|
||||
if (dst_len <= olen) {
|
||||
return (size_t)-1;
|
||||
if (memory_blocks < 2 * ARGON2_SYNC_POINTS * context->lanes) {
|
||||
memory_blocks = 2 * ARGON2_SYNC_POINTS * context->lanes;
|
||||
}
|
||||
acc = 0;
|
||||
acc_len = 0;
|
||||
buf = (const unsigned char *)src;
|
||||
size_t src_len = 32;
|
||||
while (src_len-- > 0) {
|
||||
acc = (acc << 8) + (*buf++);
|
||||
acc_len += 8;
|
||||
while (acc_len >= 6) {
|
||||
acc_len -= 6;
|
||||
*dst++ = b64_byte_to_char((acc >> acc_len) & 0x3F);
|
||||
|
||||
segment_length = memory_blocks / (context->lanes * ARGON2_SYNC_POINTS);
|
||||
/* Ensure that all segments have equal length */
|
||||
memory_blocks = segment_length * (context->lanes * ARGON2_SYNC_POINTS);
|
||||
|
||||
instance.memory = NULL;
|
||||
instance.passes = context->t_cost;
|
||||
instance.memory_blocks = memory_blocks;
|
||||
instance.segment_length = segment_length;
|
||||
instance.lane_length = segment_length * ARGON2_SYNC_POINTS;
|
||||
instance.lanes = context->lanes;
|
||||
instance.threads = context->threads;
|
||||
instance.type = type;
|
||||
|
||||
if (instance.threads > instance.lanes) {
|
||||
instance.threads = instance.lanes;
|
||||
}
|
||||
|
||||
/* 3. Initialization: Hashing inputs, allocating memory, filling first
|
||||
* blocks
|
||||
*/
|
||||
result = initialize(&instance, context);
|
||||
|
||||
if (ARGON2_OK != result) {
|
||||
return result;
|
||||
}
|
||||
|
||||
/* 4. Filling memory */
|
||||
result = fill_memory_blocks(&instance);
|
||||
|
||||
if (ARGON2_OK != result) {
|
||||
return result;
|
||||
}
|
||||
/* 5. Finalization */
|
||||
finalize(context, &instance);
|
||||
|
||||
return ARGON2_OK;
|
||||
}
|
||||
|
||||
int argon2_hash(const uint32_t t_cost, const uint32_t m_cost,
|
||||
const uint32_t parallelism, const void *pwd,
|
||||
const size_t pwdlen, const void *salt, const size_t saltlen,
|
||||
void *hash, const size_t hashlen, char *encoded,
|
||||
const size_t encodedlen, argon2_type type){
|
||||
|
||||
argon2_context context;
|
||||
int result;
|
||||
uint8_t *out;
|
||||
|
||||
if (pwdlen > ARGON2_MAX_PWD_LENGTH) {
|
||||
return ARGON2_PWD_TOO_LONG;
|
||||
}
|
||||
|
||||
if (saltlen > ARGON2_MAX_SALT_LENGTH) {
|
||||
return ARGON2_SALT_TOO_LONG;
|
||||
}
|
||||
|
||||
if (hashlen > ARGON2_MAX_OUTLEN) {
|
||||
return ARGON2_OUTPUT_TOO_LONG;
|
||||
}
|
||||
|
||||
if (hashlen < ARGON2_MIN_OUTLEN) {
|
||||
return ARGON2_OUTPUT_TOO_SHORT;
|
||||
}
|
||||
|
||||
out = malloc(hashlen);
|
||||
if (!out) {
|
||||
return ARGON2_MEMORY_ALLOCATION_ERROR;
|
||||
}
|
||||
|
||||
context.out = (uint8_t *)out;
|
||||
context.outlen = (uint32_t)hashlen;
|
||||
context.pwd = CONST_CAST(uint8_t *)pwd;
|
||||
context.pwdlen = (uint32_t)pwdlen;
|
||||
context.salt = CONST_CAST(uint8_t *)salt;
|
||||
context.saltlen = (uint32_t)saltlen;
|
||||
context.secret = NULL;
|
||||
context.secretlen = 0;
|
||||
context.ad = NULL;
|
||||
context.adlen = 0;
|
||||
context.t_cost = t_cost;
|
||||
context.m_cost = m_cost;
|
||||
context.lanes = parallelism;
|
||||
context.threads = parallelism;
|
||||
context.allocate_cbk = NULL;
|
||||
context.free_cbk = NULL;
|
||||
context.flags = ARGON2_DEFAULT_FLAGS;
|
||||
|
||||
result = argon2_ctx(&context, type);
|
||||
|
||||
if (result != ARGON2_OK) {
|
||||
clear_internal_memory(out, hashlen);
|
||||
free(out);
|
||||
return result;
|
||||
}
|
||||
|
||||
/* if raw hash requested, write it */
|
||||
if (hash) {
|
||||
memcpy(hash, out, hashlen);
|
||||
}
|
||||
|
||||
/* if encoding requested, write it */
|
||||
if (encoded && encodedlen) {
|
||||
if (encode_string(encoded, encodedlen, &context, type) != ARGON2_OK) {
|
||||
clear_internal_memory(out, hashlen); /* wipe buffers if error */
|
||||
clear_internal_memory(encoded, encodedlen);
|
||||
free(out);
|
||||
return ARGON2_ENCODING_FAIL;
|
||||
}
|
||||
}
|
||||
if (acc_len > 0) {
|
||||
*dst++ = b64_byte_to_char((acc << (6 - acc_len)) & 0x3F);
|
||||
clear_internal_memory(out, hashlen);
|
||||
free(out);
|
||||
|
||||
return ARGON2_OK;
|
||||
}
|
||||
|
||||
int argon2d_hash_encoded(const uint32_t t_cost, const uint32_t m_cost,
|
||||
const uint32_t parallelism, const void *pwd,
|
||||
const size_t pwdlen, const void *salt,
|
||||
const size_t saltlen, const size_t hashlen,
|
||||
char *encoded, const size_t encodedlen) {
|
||||
|
||||
return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen,
|
||||
NULL, hashlen, encoded, encodedlen, Argon2_d);
|
||||
}
|
||||
|
||||
int argon2d_hash_raw(const uint32_t t_cost, const uint32_t m_cost,
|
||||
const uint32_t parallelism, const void *pwd,
|
||||
const size_t pwdlen, const void *salt,
|
||||
const size_t saltlen, void *hash, const size_t hashlen) {
|
||||
|
||||
return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen,
|
||||
hash, hashlen, NULL, 0, Argon2_d);
|
||||
}
|
||||
|
||||
static int argon2_compare(const uint8_t *b1, const uint8_t *b2, size_t len) {
|
||||
size_t i;
|
||||
uint8_t d = 0U;
|
||||
|
||||
for (i = 0U; i < len; i++) {
|
||||
d |= b1[i] ^ b2[i];
|
||||
}
|
||||
*dst++ = 0;
|
||||
return olen;
|
||||
return (int)((1 & ((d - 1) >> 8)) - 1);
|
||||
}
|
||||
|
||||
/* ==================================================================== */
|
||||
/*
|
||||
* Code specific to Argon2i.
|
||||
*
|
||||
* The code below applies the following format:
|
||||
*
|
||||
* $argon2i$m=<num>,t=<num>,p=<num>[,keyid=<bin>][,data=<bin>][$<bin>[$<bin>]]
|
||||
*
|
||||
* where <num> is a decimal integer (positive, fits in an 'unsigned long')
|
||||
* and <bin> is Base64-encoded data (no '=' padding characters, no newline
|
||||
* or whitespace). The "keyid" is a binary identifier for a key (up to 8
|
||||
* bytes); "data" is associated data (up to 32 bytes). When the 'keyid'
|
||||
* (resp. the 'data') is empty, then it is ommitted from the output.
|
||||
*
|
||||
* The last two binary chunks (encoded in Base64) are, in that order,
|
||||
* the salt and the output. Both are optional, but you cannot have an
|
||||
* output without a salt. The binary salt length is between 8 and 48 bytes.
|
||||
* The output length is always exactly 32 bytes.
|
||||
*/
|
||||
int argon2_verify(const char *encoded, const void *pwd, const size_t pwdlen,
|
||||
argon2_type type) {
|
||||
|
||||
int encode_string(char *dst, size_t dst_len, argon2_context *ctx) {
|
||||
#define SS(str) \
|
||||
do { \
|
||||
size_t pp_len = strlen(str); \
|
||||
if (pp_len >= dst_len) { \
|
||||
return 0; \
|
||||
} \
|
||||
memcpy(dst, str, pp_len + 1); \
|
||||
dst += pp_len; \
|
||||
dst_len -= pp_len; \
|
||||
} while (0)
|
||||
argon2_context ctx;
|
||||
uint8_t *desired_result = NULL;
|
||||
|
||||
#define SX(x) \
|
||||
do { \
|
||||
char tmp[30]; \
|
||||
sprintf(tmp, "%lu", (unsigned long)(x)); \
|
||||
SS(tmp); \
|
||||
} while (0);
|
||||
int ret = ARGON2_OK;
|
||||
|
||||
#define SB(buf) \
|
||||
do { \
|
||||
size_t sb_len = to_base64(dst, dst_len, buf); \
|
||||
if (sb_len == (size_t)-1) { \
|
||||
return 0; \
|
||||
} \
|
||||
dst += sb_len; \
|
||||
dst_len -= sb_len; \
|
||||
} while (0);
|
||||
size_t encoded_len;
|
||||
uint32_t max_field_len;
|
||||
|
||||
SS("$argon2i$m=");
|
||||
SX(16);
|
||||
SS(",t=");
|
||||
SX(2);
|
||||
SS(",p=");
|
||||
SX(1);
|
||||
if (pwdlen > ARGON2_MAX_PWD_LENGTH) {
|
||||
return ARGON2_PWD_TOO_LONG;
|
||||
}
|
||||
|
||||
/*if (ctx->adlen > 0) {
|
||||
SS(",data=");
|
||||
SB(ctx->ad, ctx->adlen);
|
||||
}*/
|
||||
if (encoded == NULL) {
|
||||
return ARGON2_DECODING_FAIL;
|
||||
}
|
||||
|
||||
/*if (ctx->saltlen == 0)
|
||||
return 1;*/
|
||||
encoded_len = strlen(encoded);
|
||||
if (encoded_len > UINT32_MAX) {
|
||||
return ARGON2_DECODING_FAIL;
|
||||
}
|
||||
|
||||
SS("$");
|
||||
SB(ctx->salt);
|
||||
/* No field can be longer than the encoded length */
|
||||
max_field_len = (uint32_t)encoded_len;
|
||||
|
||||
/*if (ctx->outlen32 == 0)
|
||||
return 1;*/
|
||||
ctx.saltlen = max_field_len;
|
||||
ctx.outlen = max_field_len;
|
||||
|
||||
SS("$");
|
||||
SB(ctx->out);
|
||||
return 1;
|
||||
ctx.salt = malloc(ctx.saltlen);
|
||||
ctx.out = malloc(ctx.outlen);
|
||||
if (!ctx.salt || !ctx.out) {
|
||||
ret = ARGON2_MEMORY_ALLOCATION_ERROR;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
#undef SS
|
||||
#undef SX
|
||||
#undef SB
|
||||
ctx.pwd = (uint8_t *)pwd;
|
||||
ctx.pwdlen = (uint32_t)pwdlen;
|
||||
|
||||
ret = decode_string(&ctx, encoded, type);
|
||||
if (ret != ARGON2_OK) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Set aside the desired result, and get a new buffer. */
|
||||
desired_result = ctx.out;
|
||||
ctx.out = malloc(ctx.outlen);
|
||||
if (!ctx.out) {
|
||||
ret = ARGON2_MEMORY_ALLOCATION_ERROR;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = argon2_verify_ctx(&ctx, (char *)desired_result, type);
|
||||
if (ret != ARGON2_OK) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
fail:
|
||||
free(ctx.salt);
|
||||
free(ctx.out);
|
||||
free(desired_result);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int argon2d_verify(const char *encoded, const void *pwd, const size_t pwdlen) {
|
||||
|
||||
return argon2_verify(encoded, pwd, pwdlen, Argon2_d);
|
||||
}
|
||||
|
||||
int argon2d_ctx(argon2_context *context) {
|
||||
return argon2_ctx(context, Argon2_d);
|
||||
}
|
||||
|
||||
int argon2_verify_ctx(argon2_context *context, const char *hash,
|
||||
argon2_type type) {
|
||||
int ret = argon2_ctx(context, type);
|
||||
if (ret != ARGON2_OK) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (argon2_compare((uint8_t *)hash, context->out, context->outlen)) {
|
||||
return ARGON2_VERIFY_MISMATCH;
|
||||
}
|
||||
|
||||
return ARGON2_OK;
|
||||
}
|
||||
|
||||
int argon2d_verify_ctx(argon2_context *context, const char *hash) {
|
||||
return argon2_verify_ctx(context, hash, Argon2_d);
|
||||
}
|
||||
|
||||
const char *argon2_error_message(int error_code) {
|
||||
switch (error_code) {
|
||||
case ARGON2_OK:
|
||||
return "OK";
|
||||
case ARGON2_OUTPUT_PTR_NULL:
|
||||
return "Output pointer is NULL";
|
||||
case ARGON2_OUTPUT_TOO_SHORT:
|
||||
return "Output is too short";
|
||||
case ARGON2_OUTPUT_TOO_LONG:
|
||||
return "Output is too long";
|
||||
case ARGON2_PWD_TOO_SHORT:
|
||||
return "Password is too short";
|
||||
case ARGON2_PWD_TOO_LONG:
|
||||
return "Password is too long";
|
||||
case ARGON2_SALT_TOO_SHORT:
|
||||
return "Salt is too short";
|
||||
case ARGON2_SALT_TOO_LONG:
|
||||
return "Salt is too long";
|
||||
case ARGON2_AD_TOO_SHORT:
|
||||
return "Associated data is too short";
|
||||
case ARGON2_AD_TOO_LONG:
|
||||
return "Associated data is too long";
|
||||
case ARGON2_SECRET_TOO_SHORT:
|
||||
return "Secret is too short";
|
||||
case ARGON2_SECRET_TOO_LONG:
|
||||
return "Secret is too long";
|
||||
case ARGON2_TIME_TOO_SMALL:
|
||||
return "Time cost is too small";
|
||||
case ARGON2_TIME_TOO_LARGE:
|
||||
return "Time cost is too large";
|
||||
case ARGON2_MEMORY_TOO_LITTLE:
|
||||
return "Memory cost is too small";
|
||||
case ARGON2_MEMORY_TOO_MUCH:
|
||||
return "Memory cost is too large";
|
||||
case ARGON2_LANES_TOO_FEW:
|
||||
return "Too few lanes";
|
||||
case ARGON2_LANES_TOO_MANY:
|
||||
return "Too many lanes";
|
||||
case ARGON2_PWD_PTR_MISMATCH:
|
||||
return "Password pointer is NULL, but password length is not 0";
|
||||
case ARGON2_SALT_PTR_MISMATCH:
|
||||
return "Salt pointer is NULL, but salt length is not 0";
|
||||
case ARGON2_SECRET_PTR_MISMATCH:
|
||||
return "Secret pointer is NULL, but secret length is not 0";
|
||||
case ARGON2_AD_PTR_MISMATCH:
|
||||
return "Associated data pointer is NULL, but ad length is not 0";
|
||||
case ARGON2_MEMORY_ALLOCATION_ERROR:
|
||||
return "Memory allocation error";
|
||||
case ARGON2_FREE_MEMORY_CBK_NULL:
|
||||
return "The free memory callback is NULL";
|
||||
case ARGON2_ALLOCATE_MEMORY_CBK_NULL:
|
||||
return "The allocate memory callback is NULL";
|
||||
case ARGON2_INCORRECT_PARAMETER:
|
||||
return "Argon2_Context context is NULL";
|
||||
case ARGON2_INCORRECT_TYPE:
|
||||
return "There is no such version of Argon2";
|
||||
case ARGON2_OUT_PTR_MISMATCH:
|
||||
return "Output pointer mismatch";
|
||||
case ARGON2_THREADS_TOO_FEW:
|
||||
return "Not enough threads";
|
||||
case ARGON2_THREADS_TOO_MANY:
|
||||
return "Too many threads";
|
||||
case ARGON2_MISSING_ARGS:
|
||||
return "Missing arguments";
|
||||
case ARGON2_ENCODING_FAIL:
|
||||
return "Encoding failed";
|
||||
case ARGON2_DECODING_FAIL:
|
||||
return "Decoding failed";
|
||||
case ARGON2_THREAD_FAIL:
|
||||
return "Threading failure";
|
||||
case ARGON2_DECODING_LENGTH_FAIL:
|
||||
return "Some of encoded parameters are too long or too short";
|
||||
case ARGON2_VERIFY_MISMATCH:
|
||||
return "The password does not match the supplied hash";
|
||||
default:
|
||||
return "Unknown error code";
|
||||
}
|
||||
}
|
||||
|
||||
size_t argon2_encodedlen(uint32_t t_cost, uint32_t m_cost, uint32_t parallelism,
|
||||
uint32_t saltlen, uint32_t hashlen, argon2_type type) {
|
||||
return strlen("$$v=$m=,t=,p=$$") + strlen(argon2_type2string(type, 0)) +
|
||||
numlen(t_cost) + numlen(m_cost) + numlen(parallelism) +
|
||||
b64len(saltlen) + b64len(hashlen);
|
||||
}
|
|
@ -1,18 +1,27 @@
|
|||
/*
|
||||
* Argon2 source code package
|
||||
* Argon2 reference source code package - reference C implementations
|
||||
*
|
||||
* Written by Daniel Dinu and Dmitry Khovratovich, 2015
|
||||
* Copyright 2015
|
||||
* Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
|
||||
*
|
||||
* This work is licensed under a Creative Commons CC0 1.0 License/Waiver.
|
||||
* You may use this work under the terms of a Creative Commons CC0 1.0
|
||||
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
|
||||
* these licenses can be found at:
|
||||
*
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along
|
||||
* with
|
||||
* this software. If not, see
|
||||
* <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* You should have received a copy of both of these licenses along with this
|
||||
* software. If not, they may be obtained at the above URLs.
|
||||
*/
|
||||
|
||||
#ifndef ARGON2_H
|
||||
#define ARGON2_H
|
||||
|
||||
#if defined(HAVE_CONFIG_H)
|
||||
#include "config/dynamic-config.h"
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <limits.h>
|
||||
|
@ -21,8 +30,18 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*************************Argon2 input parameter
|
||||
* restrictions**************************************************/
|
||||
/* Symbols visibility control */
|
||||
#ifdef A2_VISCTL
|
||||
#define ARGON2_PUBLIC __attribute__((visibility("default")))
|
||||
#elif _MSC_VER
|
||||
#define ARGON2_PUBLIC __declspec(dllexport)
|
||||
#else
|
||||
#define ARGON2_PUBLIC
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Argon2 input parameter restrictions
|
||||
*/
|
||||
|
||||
/* Minimum and maximum number of lanes (degree of parallelism) */
|
||||
#define ARGON2_MIN_LANES UINT32_C(1)
|
||||
|
@ -43,8 +62,7 @@ extern "C" {
|
|||
#define ARGON2_MIN_MEMORY (2 * ARGON2_SYNC_POINTS) /* 2 blocks per slice */
|
||||
|
||||
#define ARGON2_MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||
/* Max memory size is half the addressing space, topping at 2^32 blocks (4 TB)
|
||||
*/
|
||||
/* Max memory size is addressing-space/2, topping at 2^32 blocks (4 TB) */
|
||||
#define ARGON2_MAX_MEMORY_BITS \
|
||||
ARGON2_MIN(UINT32_C(32), (sizeof(void *) * CHAR_BIT - 10 - 1))
|
||||
#define ARGON2_MAX_MEMORY \
|
||||
|
@ -70,65 +88,74 @@ extern "C" {
|
|||
#define ARGON2_MIN_SECRET UINT32_C(0)
|
||||
#define ARGON2_MAX_SECRET UINT32_C(0xFFFFFFFF)
|
||||
|
||||
/* Flags to determine which fields are securely wiped (default = no wipe). */
|
||||
#define ARGON2_DEFAULT_FLAGS UINT32_C(0)
|
||||
#define ARGON2_FLAG_CLEAR_PASSWORD (UINT32_C(1) << 0)
|
||||
#define ARGON2_FLAG_CLEAR_SECRET (UINT32_C(1) << 1)
|
||||
#define ARGON2_FLAG_CLEAR_MEMORY (UINT32_C(1) << 2)
|
||||
#define ARGON2_DEFAULT_FLAGS \
|
||||
(ARGON2_FLAG_CLEAR_PASSWORD | ARGON2_FLAG_CLEAR_MEMORY)
|
||||
|
||||
/* Global flag to determine if we are wiping internal memory buffers. This flag
|
||||
* is defined in core.c and deafults to 1 (wipe internal memory). */
|
||||
extern int FLAG_clear_internal_memory;
|
||||
|
||||
/* Error codes */
|
||||
typedef enum Argon2_ErrorCodes {
|
||||
ARGON2_OK = 0,
|
||||
|
||||
ARGON2_OUTPUT_PTR_NULL = 1,
|
||||
ARGON2_OUTPUT_PTR_NULL = -1,
|
||||
|
||||
ARGON2_OUTPUT_TOO_SHORT = 2,
|
||||
ARGON2_OUTPUT_TOO_LONG = 3,
|
||||
ARGON2_OUTPUT_TOO_SHORT = -2,
|
||||
ARGON2_OUTPUT_TOO_LONG = -3,
|
||||
|
||||
ARGON2_PWD_TOO_SHORT = 4,
|
||||
ARGON2_PWD_TOO_LONG = 5,
|
||||
ARGON2_PWD_TOO_SHORT = -4,
|
||||
ARGON2_PWD_TOO_LONG = -5,
|
||||
|
||||
ARGON2_SALT_TOO_SHORT = 6,
|
||||
ARGON2_SALT_TOO_LONG = 7,
|
||||
ARGON2_SALT_TOO_SHORT = -6,
|
||||
ARGON2_SALT_TOO_LONG = -7,
|
||||
|
||||
ARGON2_AD_TOO_SHORT = 8,
|
||||
ARGON2_AD_TOO_LONG = 9,
|
||||
ARGON2_AD_TOO_SHORT = -8,
|
||||
ARGON2_AD_TOO_LONG = -9,
|
||||
|
||||
ARGON2_SECRET_TOO_SHORT = 10,
|
||||
ARGON2_SECRET_TOO_LONG = 11,
|
||||
ARGON2_SECRET_TOO_SHORT = -10,
|
||||
ARGON2_SECRET_TOO_LONG = -11,
|
||||
|
||||
ARGON2_TIME_TOO_SMALL = 12,
|
||||
ARGON2_TIME_TOO_LARGE = 13,
|
||||
ARGON2_TIME_TOO_SMALL = -12,
|
||||
ARGON2_TIME_TOO_LARGE = -13,
|
||||
|
||||
ARGON2_MEMORY_TOO_LITTLE = 14,
|
||||
ARGON2_MEMORY_TOO_MUCH = 15,
|
||||
ARGON2_MEMORY_TOO_LITTLE = -14,
|
||||
ARGON2_MEMORY_TOO_MUCH = -15,
|
||||
|
||||
ARGON2_LANES_TOO_FEW = 16,
|
||||
ARGON2_LANES_TOO_MANY = 17,
|
||||
ARGON2_LANES_TOO_FEW = -16,
|
||||
ARGON2_LANES_TOO_MANY = -17,
|
||||
|
||||
ARGON2_PWD_PTR_MISMATCH = 18, /* NULL ptr with non-zero length */
|
||||
ARGON2_SALT_PTR_MISMATCH = 19, /* NULL ptr with non-zero length */
|
||||
ARGON2_SECRET_PTR_MISMATCH = 20, /* NULL ptr with non-zero length */
|
||||
ARGON2_AD_PTR_MISMATCH = 21, /* NULL ptr with non-zero length */
|
||||
ARGON2_PWD_PTR_MISMATCH = -18, /* NULL ptr with non-zero length */
|
||||
ARGON2_SALT_PTR_MISMATCH = -19, /* NULL ptr with non-zero length */
|
||||
ARGON2_SECRET_PTR_MISMATCH = -20, /* NULL ptr with non-zero length */
|
||||
ARGON2_AD_PTR_MISMATCH = -21, /* NULL ptr with non-zero length */
|
||||
|
||||
ARGON2_MEMORY_ALLOCATION_ERROR = 22,
|
||||
ARGON2_MEMORY_ALLOCATION_ERROR = -22,
|
||||
|
||||
ARGON2_FREE_MEMORY_CBK_NULL = 23,
|
||||
ARGON2_ALLOCATE_MEMORY_CBK_NULL = 24,
|
||||
ARGON2_FREE_MEMORY_CBK_NULL = -23,
|
||||
ARGON2_ALLOCATE_MEMORY_CBK_NULL = -24,
|
||||
|
||||
ARGON2_INCORRECT_PARAMETER = 25,
|
||||
ARGON2_INCORRECT_TYPE = 26,
|
||||
ARGON2_INCORRECT_PARAMETER = -25,
|
||||
ARGON2_INCORRECT_TYPE = -26,
|
||||
|
||||
ARGON2_OUT_PTR_MISMATCH = 27,
|
||||
ARGON2_OUT_PTR_MISMATCH = -27,
|
||||
|
||||
ARGON2_THREADS_TOO_FEW = 28,
|
||||
ARGON2_THREADS_TOO_MANY = 29,
|
||||
ARGON2_THREADS_TOO_FEW = -28,
|
||||
ARGON2_THREADS_TOO_MANY = -29,
|
||||
|
||||
ARGON2_MISSING_ARGS = 30,
|
||||
ARGON2_MISSING_ARGS = -30,
|
||||
|
||||
ARGON2_ERROR_CODES_LENGTH /* Do NOT remove; Do NOT add error codes after
|
||||
this
|
||||
error code */
|
||||
ARGON2_ENCODING_FAIL = -31,
|
||||
|
||||
ARGON2_DECODING_FAIL = -32,
|
||||
|
||||
ARGON2_THREAD_FAIL = -33,
|
||||
|
||||
ARGON2_DECODING_LENGTH_FAIL = -34,
|
||||
|
||||
ARGON2_VERIFY_MISMATCH = -35
|
||||
} argon2_error_codes;
|
||||
|
||||
/* Memory allocator types --- for external allocation */
|
||||
|
@ -138,152 +165,170 @@ typedef void (*deallocate_fptr)(uint8_t *memory, size_t bytes_to_allocate);
|
|||
/* Argon2 external data structures */
|
||||
|
||||
/*
|
||||
*****Context: structure to hold Argon2 inputs:
|
||||
* output array and its length,
|
||||
* password and its length,
|
||||
* salt and its length,
|
||||
* secret and its length,
|
||||
* associated data and its length,
|
||||
* number of passes, amount of used memory (in KBytes, can be rounded up a bit)
|
||||
* number of parallel threads that will be run.
|
||||
*****
|
||||
* Context: structure to hold Argon2 inputs:
|
||||
* output array and its length,
|
||||
* password and its length,
|
||||
* salt and its length,
|
||||
* secret and its length,
|
||||
* associated data and its length,
|
||||
* number of passes, amount of used memory (in KBytes, can be rounded up a bit)
|
||||
* number of parallel threads that will be run.
|
||||
* All the parameters above affect the output hash value.
|
||||
* Additionally, two function pointers can be provided to allocate and
|
||||
deallocate the memory (if NULL, memory will be allocated internally).
|
||||
* deallocate the memory (if NULL, memory will be allocated internally).
|
||||
* Also, three flags indicate whether to erase password, secret as soon as they
|
||||
are pre-hashed (and thus not needed anymore), and the entire memory
|
||||
****************************
|
||||
Simplest situation: you have output array out[8], password is stored in
|
||||
pwd[32], salt is stored in salt[16], you do not have keys nor associated data.
|
||||
You need to spend 1 GB of RAM and you run 5 passes of Argon2d with 4 parallel
|
||||
lanes.
|
||||
You want to erase the password, but you're OK with last pass not being erased.
|
||||
You want to use the default memory allocator.
|
||||
* are pre-hashed (and thus not needed anymore), and the entire memory
|
||||
*****
|
||||
* Simplest situation: you have output array out[8], password is stored in
|
||||
* pwd[32], salt is stored in salt[16], you do not have keys nor associated
|
||||
* data. You need to spend 1 GB of RAM and you run 5 passes of Argon2d with
|
||||
* 4 parallel lanes.
|
||||
* You want to erase the password, but you're OK with last pass not being
|
||||
* erased. You want to use the default memory allocator.
|
||||
* Then you initialize:
|
||||
Argon2_Context(out,8,pwd,32,salt,16,NULL,0,NULL,0,5,1<<20,4,4,NULL,NULL,true,false,false,false)
|
||||
*/
|
||||
typedef struct Argon2_Context {
|
||||
uint8_t *out; /* output array */
|
||||
uint32_t outlen; /* digest length */
|
||||
|
||||
uint8_t *pwd; /* password array */
|
||||
uint32_t pwdlen; /* password length */
|
||||
|
||||
uint8_t *salt; /* salt array */
|
||||
/*uint8_t *secret;*/ /* key array */
|
||||
/*uint8_t *ad;*/ /* associated data array */
|
||||
uint32_t saltlen; /* salt length */
|
||||
|
||||
uint8_t *secret; /* key array */
|
||||
uint32_t secretlen; /* key length */
|
||||
|
||||
uint8_t *ad; /* associated data array */
|
||||
uint32_t adlen; /* associated data length */
|
||||
|
||||
uint32_t t_cost; /* number of passes */
|
||||
uint32_t m_cost; /* amount of memory requested (KB) */
|
||||
uint32_t lanes; /* number of lanes */
|
||||
uint32_t threads; /* maximum number of threads */
|
||||
|
||||
allocate_fptr allocate_cbk; /* pointer to memory allocator */
|
||||
deallocate_fptr free_cbk; /* pointer to memory deallocator */
|
||||
|
||||
/*uint32_t outlen;*/ /* digest length */
|
||||
uint32_t pwdlen; /* password length */
|
||||
/*uint32_t saltlen;*/ /* salt length */
|
||||
/*uint32_t secretlen;*/ /* key length */
|
||||
/*uint32_t adlen;*/ /* associated data length */
|
||||
/*uint32_t t_cost;*/ /* number of passes */
|
||||
/*uint32_t m_cost;*/ /* amount of memory requested (KB) */
|
||||
/*uint32_t lanes;*/ /* number of lanes */
|
||||
/*uint32_t threads;*/ /* maximum number of threads */
|
||||
/*uint32_t flags;*/ /* array of bool options */
|
||||
|
||||
uint32_t flags; /* array of bool options */
|
||||
} argon2_context;
|
||||
|
||||
/* Argon2 primitive type */
|
||||
typedef enum Argon2_type {
|
||||
Argon2_d = 0
|
||||
} argon2_type;
|
||||
|
||||
/*
|
||||
* Function that gives the string representation of an argon2_type.
|
||||
* @param type The argon2_type that we want the string for
|
||||
* @param uppercase Whether the string should have the first letter uppercase
|
||||
* @return NULL if invalid type, otherwise the string representation.
|
||||
*/
|
||||
ARGON2_PUBLIC const char *argon2_type2string(argon2_type type, int uppercase);
|
||||
|
||||
/*
|
||||
* Function that performs memory-hard hashing with certain degree of parallelism
|
||||
* @param context Pointer to the Argon2 internal structure
|
||||
* @return Error code if smth is wrong, ARGON2_OK otherwise
|
||||
*/
|
||||
ARGON2_PUBLIC int argon2_ctx(argon2_context *context, argon2_type type);
|
||||
|
||||
/**
|
||||
* Function to hash the inputs in the memory-hard fashion (uses Argon2i)
|
||||
* @param out Pointer to the memory where the hash digest will be written
|
||||
* @param outlen Digest length in bytes
|
||||
* @param in Pointer to the input (password)
|
||||
* @param inlen Input length in bytes
|
||||
* @param salt Pointer to the salt
|
||||
* @param saltlen Salt length in bytes
|
||||
* @pre @a out must have at least @a outlen bytes allocated
|
||||
* @pre @a in must be at least @inlen bytes long
|
||||
* @pre @a saltlen must be at least @saltlen bytes long
|
||||
* @return Zero if successful, 1 otherwise.
|
||||
* Hashes a password with Argon2i, producing a raw hash by allocating memory at
|
||||
* @hash
|
||||
* @param t_cost Number of iterations
|
||||
* @param m_cost Sets memory usage to m_cost kibibytes
|
||||
* @param parallelism Number of threads and compute lanes
|
||||
* @param pwd Pointer to password
|
||||
* @param pwdlen Password size in bytes
|
||||
* @param salt Pointer to salt
|
||||
* @param saltlen Salt size in bytes
|
||||
* @param hash Buffer where to write the raw hash - updated by the function
|
||||
* @param hashlen Desired length of the hash in bytes
|
||||
* @pre Different parallelism levels will give different results
|
||||
* @pre Returns ARGON2_OK if successful
|
||||
*/
|
||||
/*int hash_argon2i(void *out, size_t outlen, const void *in, size_t inlen,
|
||||
const void *salt, size_t saltlen, unsigned int t_cost,
|
||||
unsigned int m_cost);*/
|
||||
ARGON2_PUBLIC int argon2d_hash_raw(const uint32_t t_cost, const uint32_t m_cost,
|
||||
const uint32_t parallelism, const void *pwd,
|
||||
const size_t pwdlen, const void *salt,
|
||||
const size_t saltlen, void *hash,
|
||||
const size_t hashlen);
|
||||
|
||||
/* same for argon2d */
|
||||
/*int hash_argon2d(void *out, size_t outlen, const void *in, size_t inlen,
|
||||
const void *salt, size_t saltlen, unsigned int t_cost,
|
||||
unsigned int m_cost);*/
|
||||
ARGON2_PUBLIC int argon2d_hash_encoded(const uint32_t t_cost,
|
||||
const uint32_t m_cost,
|
||||
const uint32_t parallelism,
|
||||
const void *pwd, const size_t pwdlen,
|
||||
const void *salt, const size_t saltlen,
|
||||
const size_t hashlen, char *encoded,
|
||||
const size_t encodedlen);
|
||||
|
||||
/*
|
||||
* **************Argon2d: Version of Argon2 that picks memory blocks depending
|
||||
/* generic function underlying the above ones */
|
||||
ARGON2_PUBLIC int argon2_hash(const uint32_t t_cost, const uint32_t m_cost,
|
||||
const uint32_t parallelism, const void *pwd,
|
||||
const size_t pwdlen, const void *salt,
|
||||
const size_t saltlen, void *hash,
|
||||
const size_t hashlen, char *encoded,
|
||||
const size_t encodedlen, argon2_type type);
|
||||
|
||||
/**
|
||||
* Verifies a password against an encoded string
|
||||
* Encoded string is restricted as in validate_inputs()
|
||||
* @param encoded String encoding parameters, salt, hash
|
||||
* @param pwd Pointer to password
|
||||
* @pre Returns ARGON2_OK if successful
|
||||
*/
|
||||
ARGON2_PUBLIC int argon2d_verify(const char *encoded, const void *pwd,
|
||||
const size_t pwdlen);
|
||||
|
||||
/* generic function underlying the above ones */
|
||||
ARGON2_PUBLIC int argon2_verify(const char *encoded, const void *pwd,
|
||||
const size_t pwdlen, argon2_type type);
|
||||
|
||||
/**
|
||||
* Argon2d: Version of Argon2 that picks memory blocks depending
|
||||
* on the password and salt. Only for side-channel-free
|
||||
* environment!!***************
|
||||
* environment!!
|
||||
*****
|
||||
* @param context Pointer to current Argon2 context
|
||||
* @return Zero if successful, a non zero error code otherwise
|
||||
*/
|
||||
int argon2d(argon2_context *context);
|
||||
ARGON2_PUBLIC int argon2d_ctx(argon2_context *context);
|
||||
|
||||
/*
|
||||
* * **************Argon2i: Version of Argon2 that picks memory blocks
|
||||
*independent on the password and salt. Good for side-channels,
|
||||
******************* but worse w.r.t. tradeoff attacks if
|
||||
*******************only one pass is used***************
|
||||
* @param context Pointer to current Argon2 context
|
||||
* @return Zero if successful, a non zero error code otherwise
|
||||
*/
|
||||
int argon2i(argon2_context *context);
|
||||
|
||||
/*
|
||||
* * **************Argon2di: Reserved name***************
|
||||
* @param context Pointer to current Argon2 context
|
||||
* @return Zero if successful, a non zero error code otherwise
|
||||
*/
|
||||
int argon2di(argon2_context *context);
|
||||
|
||||
/*
|
||||
* * **************Argon2ds: Argon2d hardened against GPU attacks, 20%
|
||||
* slower***************
|
||||
* @param context Pointer to current Argon2 context
|
||||
* @return Zero if successful, a non zero error code otherwise
|
||||
*/
|
||||
int argon2ds(argon2_context *context);
|
||||
|
||||
/*
|
||||
* * **************Argon2id: First half-pass over memory is
|
||||
*password-independent, the rest are password-dependent
|
||||
********************OK against side channels: they reduce to 1/2-pass
|
||||
*Argon2i***************
|
||||
* @param context Pointer to current Argon2 context
|
||||
* @return Zero if successful, a non zero error code otherwise
|
||||
*/
|
||||
int argon2id(argon2_context *context);
|
||||
|
||||
/*
|
||||
/**
|
||||
* Verify if a given password is correct for Argon2d hashing
|
||||
* @param context Pointer to current Argon2 context
|
||||
* @param hash The password hash to verify. The length of the hash is
|
||||
* specified by the context outlen member
|
||||
* @return Zero if successful, a non zero error code otherwise
|
||||
*/
|
||||
int verify_d(argon2_context *context, const char *hash);
|
||||
ARGON2_PUBLIC int argon2d_verify_ctx(argon2_context *context, const char *hash);
|
||||
|
||||
/*
|
||||
/* generic function underlying the above ones */
|
||||
ARGON2_PUBLIC int argon2_verify_ctx(argon2_context *context, const char *hash,
|
||||
argon2_type type);
|
||||
|
||||
/**
|
||||
* Get the associated error message for given error code
|
||||
* @return The error message associated with the given error code
|
||||
*/
|
||||
const char *error_message(int error_code);
|
||||
ARGON2_PUBLIC const char *argon2_error_message(int error_code);
|
||||
|
||||
/* ==================================================================== */
|
||||
/*
|
||||
* Code specific to Argon2i.
|
||||
*
|
||||
* The code below applies the following format:
|
||||
*
|
||||
* $argon2i$m=<num>,t=<num>,p=<num>[,keyid=<bin>][,data=<bin>][$<bin>[$<bin>]]
|
||||
*
|
||||
* where <num> is a decimal integer (positive, fits in an 'unsigned long')
|
||||
* and <bin> is Base64-encoded data (no '=' padding characters, no newline
|
||||
* or whitespace). The "keyid" is a binary identifier for a key (up to 8
|
||||
* bytes); "data" is associated data (up to 32 bytes). When the 'keyid'
|
||||
* (resp. the 'data') is empty, then it is ommitted from the output.
|
||||
*
|
||||
* The last two binary chunks (encoded in Base64) are, in that order,
|
||||
* the salt and the output. Both are optional, but you cannot have an
|
||||
* output without a salt. The binary salt length is between 8 and 48 bytes.
|
||||
* The output length is always exactly 32 bytes.
|
||||
/**
|
||||
* Returns the encoded hash length for the given input parameters
|
||||
* @param t_cost Number of iterations
|
||||
* @param m_cost Memory usage in kibibytes
|
||||
* @param parallelism Number of threads; used to compute lanes
|
||||
* @param saltlen Salt size in bytes
|
||||
* @param hashlen Hash size in bytes
|
||||
* @param type The argon2_type that we want the encoded length for
|
||||
* @return The encoded hash length in bytes
|
||||
*/
|
||||
|
||||
int encode_string(char *dst, size_t dst_len, argon2_context *ctx);
|
||||
ARGON2_PUBLIC size_t argon2_encodedlen(uint32_t t_cost, uint32_t m_cost,
|
||||
uint32_t parallelism, uint32_t saltlen,
|
||||
uint32_t hashlen, argon2_type type);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
|
|
|
@ -1,111 +0,0 @@
|
|||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#ifdef _MSC_VER
|
||||
#include <intrin.h>
|
||||
#endif
|
||||
|
||||
#include "argon2.h"
|
||||
|
||||
static uint64_t rdtsc(void) {
|
||||
#ifdef _MSC_VER
|
||||
return __rdtsc();
|
||||
#else
|
||||
#if defined(__amd64__) || defined(__x86_64__)
|
||||
uint64_t rax, rdx;
|
||||
__asm__ __volatile__("rdtsc" : "=a"(rax), "=d"(rdx) : :);
|
||||
return (rdx << 32) | rax;
|
||||
#elif defined(__i386__) || defined(__i386) || defined(__X86__)
|
||||
uint64_t rax;
|
||||
__asm__ __volatile__("rdtsc" : "=A"(rax) : :);
|
||||
return rax;
|
||||
#else
|
||||
#error "Not implemented!"
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Benchmarks Argon2 with salt length 16, password length 16, t_cost 1,
|
||||
and different m_cost and threads
|
||||
*/
|
||||
static void benchmark() {
|
||||
#define BENCH_OUTLEN 16
|
||||
#define BENCH_INLEN 16
|
||||
const uint32_t inlen = BENCH_INLEN;
|
||||
const unsigned outlen = BENCH_OUTLEN;
|
||||
unsigned char out[BENCH_OUTLEN];
|
||||
unsigned char pwd_array[BENCH_INLEN];
|
||||
unsigned char salt_array[BENCH_INLEN];
|
||||
#undef BENCH_INLEN
|
||||
#undef BENCH_OUTLEN
|
||||
|
||||
uint32_t t_cost = 1;
|
||||
uint32_t m_cost;
|
||||
uint32_t thread_test[6] = {1, 2, 4, 6, 8, 16};
|
||||
|
||||
memset(pwd_array, 0, inlen);
|
||||
memset(salt_array, 1, inlen);
|
||||
|
||||
for (m_cost = (uint32_t)1 << 10; m_cost <= (uint32_t)1 << 22; m_cost *= 2) {
|
||||
unsigned i;
|
||||
for (i = 0; i < 6; ++i) {
|
||||
argon2_context context;
|
||||
uint32_t thread_n = thread_test[i];
|
||||
uint64_t stop_cycles, stop_cycles_i;
|
||||
clock_t stop_time;
|
||||
uint64_t delta_d, delta_i;
|
||||
double mcycles_d, mcycles_i, run_time;
|
||||
|
||||
clock_t start_time = clock();
|
||||
uint64_t start_cycles = rdtsc();
|
||||
|
||||
context.out = out;
|
||||
context.outlen = outlen;
|
||||
context.pwd = pwd_array;
|
||||
context.pwdlen = inlen;
|
||||
context.salt = salt_array;
|
||||
context.saltlen = inlen;
|
||||
context.secret = NULL;
|
||||
context.secretlen = 0;
|
||||
context.ad = NULL;
|
||||
context.adlen = 0;
|
||||
context.t_cost = t_cost;
|
||||
context.m_cost = m_cost;
|
||||
context.lanes = thread_n;
|
||||
context.threads = thread_n;
|
||||
context.allocate_cbk = NULL;
|
||||
context.free_cbk = NULL;
|
||||
context.flags = 0;
|
||||
|
||||
argon2d(&context);
|
||||
stop_cycles = rdtsc();
|
||||
argon2i(&context);
|
||||
stop_cycles_i = rdtsc();
|
||||
stop_time = clock();
|
||||
|
||||
delta_d = (stop_cycles - start_cycles) / (m_cost);
|
||||
delta_i = (stop_cycles_i - stop_cycles) / (m_cost);
|
||||
mcycles_d = (double)(stop_cycles - start_cycles) / (1UL << 20);
|
||||
mcycles_i = (double)(stop_cycles_i - stop_cycles) / (1UL << 20);
|
||||
printf("Argon2d %d iterations %d MiB %d threads: %2.2f cpb %2.2f "
|
||||
"Mcycles \n",
|
||||
t_cost, m_cost >> 10, thread_n, (float)delta_d / 1024,
|
||||
mcycles_d);
|
||||
printf("Argon2i %d iterations %d MiB %d threads: %2.2f cpb %2.2f "
|
||||
"Mcycles \n",
|
||||
t_cost, m_cost >> 10, thread_n, (float)delta_i / 1024,
|
||||
mcycles_i);
|
||||
|
||||
run_time = ((double)stop_time - start_time) / (CLOCKS_PER_SEC);
|
||||
printf("%2.4f seconds\n\n", run_time);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
benchmark();
|
||||
return ARGON2_OK;
|
||||
}
|
|
@ -1,162 +0,0 @@
|
|||
#ifndef BLAKE_ROUND_MKA_OPT_H
|
||||
#define BLAKE_ROUND_MKA_OPT_H
|
||||
|
||||
#include "blake2-impl.h"
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#include <intrin.h>
|
||||
#endif
|
||||
|
||||
#include <immintrin.h>
|
||||
#if defined(__XOP__) && (defined(__GNUC__) || defined(__clang__))
|
||||
#include <x86intrin.h>
|
||||
#endif
|
||||
|
||||
#if !defined(__XOP__)
|
||||
#if defined(__SSSE3__)
|
||||
#define r16 \
|
||||
(_mm_setr_epi8(2, 3, 4, 5, 6, 7, 0, 1, 10, 11, 12, 13, 14, 15, 8, 9))
|
||||
#define r24 \
|
||||
(_mm_setr_epi8(3, 4, 5, 6, 7, 0, 1, 2, 11, 12, 13, 14, 15, 8, 9, 10))
|
||||
#define _mm_roti_epi64(x, c) \
|
||||
(-(c) == 32) \
|
||||
? _mm_shuffle_epi32((x), _MM_SHUFFLE(2, 3, 0, 1)) \
|
||||
: (-(c) == 24) \
|
||||
? _mm_shuffle_epi8((x), r24) \
|
||||
: (-(c) == 16) \
|
||||
? _mm_shuffle_epi8((x), r16) \
|
||||
: (-(c) == 63) \
|
||||
? _mm_xor_si128(_mm_srli_epi64((x), -(c)), \
|
||||
_mm_add_epi64((x), (x))) \
|
||||
: _mm_xor_si128(_mm_srli_epi64((x), -(c)), \
|
||||
_mm_slli_epi64((x), 64 - (-(c))))
|
||||
#else /* defined(__SSE2__) */
|
||||
#define _mm_roti_epi64(r, c) \
|
||||
_mm_xor_si128(_mm_srli_epi64((r), -(c)), _mm_slli_epi64((r), 64 - (-(c))))
|
||||
#endif
|
||||
#else
|
||||
#endif
|
||||
|
||||
static BLAKE2_INLINE __m128i fBlaMka(__m128i x, __m128i y) {
|
||||
const __m128i z = _mm_mul_epu32(x, y);
|
||||
return _mm_add_epi64(_mm_add_epi64(x, y), _mm_add_epi64(z, z));
|
||||
}
|
||||
|
||||
#define G1(A0, B0, C0, D0, A1, B1, C1, D1) \
|
||||
do { \
|
||||
A0 = fBlaMka(A0, B0); \
|
||||
A1 = fBlaMka(A1, B1); \
|
||||
\
|
||||
D0 = _mm_xor_si128(D0, A0); \
|
||||
D1 = _mm_xor_si128(D1, A1); \
|
||||
\
|
||||
D0 = _mm_roti_epi64(D0, -32); \
|
||||
D1 = _mm_roti_epi64(D1, -32); \
|
||||
\
|
||||
C0 = fBlaMka(C0, D0); \
|
||||
C1 = fBlaMka(C1, D1); \
|
||||
\
|
||||
B0 = _mm_xor_si128(B0, C0); \
|
||||
B1 = _mm_xor_si128(B1, C1); \
|
||||
\
|
||||
B0 = _mm_roti_epi64(B0, -24); \
|
||||
B1 = _mm_roti_epi64(B1, -24); \
|
||||
} while ((void)0, 0)
|
||||
|
||||
#define G2(A0, B0, C0, D0, A1, B1, C1, D1) \
|
||||
do { \
|
||||
A0 = fBlaMka(A0, B0); \
|
||||
A1 = fBlaMka(A1, B1); \
|
||||
\
|
||||
D0 = _mm_xor_si128(D0, A0); \
|
||||
D1 = _mm_xor_si128(D1, A1); \
|
||||
\
|
||||
D0 = _mm_roti_epi64(D0, -16); \
|
||||
D1 = _mm_roti_epi64(D1, -16); \
|
||||
\
|
||||
C0 = fBlaMka(C0, D0); \
|
||||
C1 = fBlaMka(C1, D1); \
|
||||
\
|
||||
B0 = _mm_xor_si128(B0, C0); \
|
||||
B1 = _mm_xor_si128(B1, C1); \
|
||||
\
|
||||
B0 = _mm_roti_epi64(B0, -63); \
|
||||
B1 = _mm_roti_epi64(B1, -63); \
|
||||
} while ((void)0, 0)
|
||||
|
||||
#if defined(__SSSE3__)
|
||||
#define DIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1) \
|
||||
do { \
|
||||
__m128i t0 = _mm_alignr_epi8(B1, B0, 8); \
|
||||
__m128i t1 = _mm_alignr_epi8(B0, B1, 8); \
|
||||
B0 = t0; \
|
||||
B1 = t1; \
|
||||
\
|
||||
t0 = C0; \
|
||||
C0 = C1; \
|
||||
C1 = t0; \
|
||||
\
|
||||
t0 = _mm_alignr_epi8(D1, D0, 8); \
|
||||
t1 = _mm_alignr_epi8(D0, D1, 8); \
|
||||
D0 = t1; \
|
||||
D1 = t0; \
|
||||
} while ((void)0, 0)
|
||||
|
||||
#define UNDIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1) \
|
||||
do { \
|
||||
__m128i t0 = _mm_alignr_epi8(B0, B1, 8); \
|
||||
__m128i t1 = _mm_alignr_epi8(B1, B0, 8); \
|
||||
B0 = t0; \
|
||||
B1 = t1; \
|
||||
\
|
||||
t0 = C0; \
|
||||
C0 = C1; \
|
||||
C1 = t0; \
|
||||
\
|
||||
t0 = _mm_alignr_epi8(D0, D1, 8); \
|
||||
t1 = _mm_alignr_epi8(D1, D0, 8); \
|
||||
D0 = t1; \
|
||||
D1 = t0; \
|
||||
} while ((void)0, 0)
|
||||
#else /* SSE2 */
|
||||
#define DIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1) \
|
||||
do { \
|
||||
__m128i t0 = D0; \
|
||||
__m128i t1 = B0; \
|
||||
D0 = C0; \
|
||||
C0 = C1; \
|
||||
C1 = D0; \
|
||||
D0 = _mm_unpackhi_epi64(D1, _mm_unpacklo_epi64(t0, t0)); \
|
||||
D1 = _mm_unpackhi_epi64(t0, _mm_unpacklo_epi64(D1, D1)); \
|
||||
B0 = _mm_unpackhi_epi64(B0, _mm_unpacklo_epi64(B1, B1)); \
|
||||
B1 = _mm_unpackhi_epi64(B1, _mm_unpacklo_epi64(t1, t1)); \
|
||||
} while ((void)0, 0)
|
||||
|
||||
#define UNDIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1) \
|
||||
do { \
|
||||
__m128i t0 = C0; \
|
||||
C0 = C1; \
|
||||
C1 = t0; \
|
||||
t0 = B0; \
|
||||
__m128i t1 = D0; \
|
||||
B0 = _mm_unpackhi_epi64(B1, _mm_unpacklo_epi64(B0, B0)); \
|
||||
B1 = _mm_unpackhi_epi64(t0, _mm_unpacklo_epi64(B1, B1)); \
|
||||
D0 = _mm_unpackhi_epi64(D0, _mm_unpacklo_epi64(D1, D1)); \
|
||||
D1 = _mm_unpackhi_epi64(D1, _mm_unpacklo_epi64(t1, t1)); \
|
||||
} while ((void)0, 0)
|
||||
#endif
|
||||
|
||||
#define BLAKE2_ROUND(A0, A1, B0, B1, C0, C1, D0, D1) \
|
||||
do { \
|
||||
G1(A0, B0, C0, D0, A1, B1, C1, D1); \
|
||||
G2(A0, B0, C0, D0, A1, B1, C1, D1); \
|
||||
\
|
||||
DIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1); \
|
||||
\
|
||||
G1(A0, B0, C0, D0, A1, B1, C1, D1); \
|
||||
G2(A0, B0, C0, D0, A1, B1, C1, D1); \
|
||||
\
|
||||
UNDIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1); \
|
||||
} while ((void)0, 0)
|
||||
|
||||
#endif
|
|
@ -1,305 +0,0 @@
|
|||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "blake2/blake2.h"
|
||||
#include "blake2/blake2-impl.h"
|
||||
|
||||
static const uint64_t blake2b_IV[8] = {
|
||||
UINT64_C(0x6a09e667f3bcc908), UINT64_C(0xbb67ae8584caa73b),
|
||||
UINT64_C(0x3c6ef372fe94f82b), UINT64_C(0xa54ff53a5f1d36f1),
|
||||
UINT64_C(0x510e527fade682d1), UINT64_C(0x9b05688c2b3e6c1f),
|
||||
UINT64_C(0x1f83d9abfb41bd6b), UINT64_C(0x5be0cd19137e2179)
|
||||
};
|
||||
|
||||
static const unsigned int blake2b_sigma[12][16] = {
|
||||
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
|
||||
{14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3},
|
||||
{11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4},
|
||||
{7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8},
|
||||
{9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13},
|
||||
{2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9},
|
||||
{12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11},
|
||||
{13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10},
|
||||
{6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5},
|
||||
{10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0},
|
||||
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
|
||||
{14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3},
|
||||
};
|
||||
|
||||
static BLAKE2_INLINE void blake2b_set_lastnode(blake2b_state *S) {
|
||||
S->f[1] = (uint64_t)-1;
|
||||
}
|
||||
|
||||
static BLAKE2_INLINE void blake2b_set_lastblock(blake2b_state *S) {
|
||||
if (S->last_node) {
|
||||
blake2b_set_lastnode(S);
|
||||
}
|
||||
S->f[0] = (uint64_t)-1;
|
||||
}
|
||||
|
||||
static BLAKE2_INLINE void blake2b_increment_counter(blake2b_state *S,
|
||||
uint64_t inc) {
|
||||
S->t[0] += inc;
|
||||
S->t[1] += (S->t[0] < inc);
|
||||
}
|
||||
|
||||
static BLAKE2_INLINE void blake2b_invalidate_state(blake2b_state *S) {
|
||||
burn(S, sizeof(*S)); /* wipe */
|
||||
blake2b_set_lastblock(S); /* invalidate for further use */
|
||||
}
|
||||
|
||||
static BLAKE2_INLINE void blake2b_init0(blake2b_state *S) {
|
||||
memset(S, 0, sizeof(*S));
|
||||
memcpy(S->h, blake2b_IV, sizeof(S->h));
|
||||
}
|
||||
|
||||
|
||||
/*void print_state(blake2b_state BlakeHash) {
|
||||
printf(".h = {UINT64_C(%" PRIu64 "), UINT64_C(%" PRIu64 "),\n"
|
||||
"UINT64_C(%" PRIu64 "), UINT64_C(%" PRIu64 "),\n"
|
||||
"UINT64_C(%" PRIu64 "), UINT64_C(%" PRIu64 "),\n"
|
||||
"UINT64_C(%" PRIu64 "), UINT64_C(%" PRIu64 ")},\n"
|
||||
".t = {UINT64_C(%" PRIu64 "), UINT64_C(%" PRIu64 ")},\n"
|
||||
".f = {UINT64_C(%" PRIu64 "), UINT64_C(%" PRIu64 ")}\n",
|
||||
BlakeHash.h[0], BlakeHash.h[1], BlakeHash.h[2], BlakeHash.h[3],
|
||||
BlakeHash.h[4], BlakeHash.h[5], BlakeHash.h[6], BlakeHash.h[7],
|
||||
BlakeHash.t[0], BlakeHash.t[1],
|
||||
BlakeHash.f[0], BlakeHash.f[1]);
|
||||
printf(".buf = {");
|
||||
for (register uint8_t i = 0; i < BLAKE2B_BLOCKBYTES; i++)
|
||||
printf("%" PRIu8 ", ", BlakeHash.buf[i]);
|
||||
puts("\n");
|
||||
printf("}\n.buflen = %d\n.outlen = %d\n",
|
||||
BlakeHash.buflen, BlakeHash.outlen);
|
||||
printf(".last_node = %" PRIu8 "\n", BlakeHash.last_node);
|
||||
fflush(stdout);
|
||||
}*/
|
||||
|
||||
static const blake2b_state miou = {
|
||||
.h = {
|
||||
UINT64_C(7640891576939301128), UINT64_C(13503953896175478587),
|
||||
UINT64_C(4354685564936845355), UINT64_C(11912009170470909681),
|
||||
UINT64_C(5840696475078001361), UINT64_C(11170449401992604703),
|
||||
UINT64_C(2270897969802886507), UINT64_C(6620516959819538809)
|
||||
},
|
||||
.t = {UINT64_C(0), UINT64_C(0)},
|
||||
.f = {UINT64_C(0), UINT64_C(0)},
|
||||
.buf = {
|
||||
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, 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, 0, 0
|
||||
},
|
||||
.buflen = 0,
|
||||
.outlen = 64,
|
||||
.last_node = 0
|
||||
};
|
||||
|
||||
|
||||
int blake2b_init_param(blake2b_state *S, const blake2b_param *P) {
|
||||
const unsigned char *p = (const unsigned char *)P;
|
||||
unsigned int i;
|
||||
|
||||
if (NULL == P || NULL == S) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
blake2b_init0(S);
|
||||
|
||||
/* IV XOR Parameter Block */
|
||||
for (i = 0; i < 8; ++i) {
|
||||
S->h[i] ^= load64(&p[i * sizeof(S->h[i])]);
|
||||
}
|
||||
S->outlen = P->digest_length;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void compare_buffs(uint64_t *h, size_t outlen)
|
||||
{
|
||||
// printf("CMP : %d", memcmp(h, miou.h, 8*(sizeof(uint64_t))));
|
||||
printf("miou : %" PRIu64 " - h : %" PRIu64 " - outlen : %ld\n", miou.h[0], h[0], outlen);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
/* Sequential blake2b initialization */
|
||||
int blake2b_init(blake2b_state *S, size_t outlen) {
|
||||
memcpy(S, &miou, sizeof(*S));
|
||||
S->h[0] += outlen;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void print64(const char *name, const uint64_t *array, uint16_t size) {
|
||||
printf("%s = {", name);
|
||||
for (uint8_t i = 0; i < size; i++) printf("UINT64_C(%" PRIu64 "), ", array[i]);
|
||||
printf("};\n");
|
||||
}
|
||||
int blake2b_init_key(blake2b_state *S, size_t outlen, const void *key,
|
||||
size_t keylen) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void blake2b_compress(blake2b_state *S, const uint8_t *block) {
|
||||
uint64_t m[16];
|
||||
uint64_t v[16];
|
||||
unsigned int i, r;
|
||||
|
||||
for (i = 0; i < 16; ++i) {
|
||||
m[i] = load64(block + i * 8);
|
||||
}
|
||||
|
||||
for (i = 0; i < 8; ++i) {
|
||||
v[i] = S->h[i];
|
||||
}
|
||||
|
||||
v[8] = blake2b_IV[0];
|
||||
v[9] = blake2b_IV[1];
|
||||
v[10] = blake2b_IV[2];
|
||||
v[11] = blake2b_IV[3];
|
||||
v[12] = blake2b_IV[4] ^ S->t[0];
|
||||
v[13] = blake2b_IV[5]/* ^ S->t[1]*/;
|
||||
v[14] = blake2b_IV[6] ^ S->f[0];
|
||||
v[15] = blake2b_IV[7]/* ^ S->f[1]*/;
|
||||
|
||||
#define G(r, i, a, b, c, d) \
|
||||
do { \
|
||||
a = a + b + m[blake2b_sigma[r][2 * i + 0]]; \
|
||||
d = rotr64(d ^ a, 32); \
|
||||
c = c + d; \
|
||||
b = rotr64(b ^ c, 24); \
|
||||
a = a + b + m[blake2b_sigma[r][2 * i + 1]]; \
|
||||
d = rotr64(d ^ a, 16); \
|
||||
c = c + d; \
|
||||
b = rotr64(b ^ c, 63); \
|
||||
} while ((void)0, 0)
|
||||
|
||||
#define ROUND(r) \
|
||||
do { \
|
||||
G(r, 0, v[0], v[4], v[8], v[12]); \
|
||||
G(r, 1, v[1], v[5], v[9], v[13]); \
|
||||
G(r, 2, v[2], v[6], v[10], v[14]); \
|
||||
G(r, 3, v[3], v[7], v[11], v[15]); \
|
||||
G(r, 4, v[0], v[5], v[10], v[15]); \
|
||||
G(r, 5, v[1], v[6], v[11], v[12]); \
|
||||
G(r, 6, v[2], v[7], v[8], v[13]); \
|
||||
G(r, 7, v[3], v[4], v[9], v[14]); \
|
||||
} while ((void)0, 0)
|
||||
|
||||
for (r = 0; r < 12; ++r) ROUND(r);
|
||||
|
||||
for (i = 0; i < 8; ++i) S->h[i] = S->h[i] ^ v[i] ^ v[i + 8];
|
||||
|
||||
#undef G
|
||||
#undef ROUND
|
||||
}
|
||||
|
||||
int blake2b_update(blake2b_state *S, const void *in, size_t inlen) {
|
||||
const uint8_t *pin = (const uint8_t *)in;
|
||||
/* Complete current block */
|
||||
memcpy(&S->buf[4], pin, 124);
|
||||
blake2b_increment_counter(S, BLAKE2B_BLOCKBYTES);
|
||||
blake2b_compress(S, S->buf);
|
||||
S->buflen = 0;
|
||||
pin += 124;
|
||||
|
||||
register int8_t i = 7;
|
||||
/* Avoid buffer copies when possible */
|
||||
while (i--) {
|
||||
blake2b_increment_counter(S, BLAKE2B_BLOCKBYTES);
|
||||
blake2b_compress(S, pin);
|
||||
pin += BLAKE2B_BLOCKBYTES;
|
||||
}
|
||||
memcpy(&S->buf[S->buflen], pin, 4);
|
||||
S->buflen += 4;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void my_blake2b_update(blake2b_state *S, const void *in, size_t inlen) {
|
||||
|
||||
memcpy(&S->buf[S->buflen], in, inlen);
|
||||
S->buflen += (unsigned int)inlen;
|
||||
}
|
||||
|
||||
int blake2b_final(blake2b_state *S, void *out, size_t outlen) {
|
||||
uint8_t buffer[BLAKE2B_OUTBYTES] = {0};
|
||||
unsigned int i;
|
||||
|
||||
blake2b_increment_counter(S, S->buflen);
|
||||
blake2b_set_lastblock(S);
|
||||
memset(&S->buf[S->buflen], 0, BLAKE2B_BLOCKBYTES - S->buflen); /* Padding */
|
||||
blake2b_compress(S, S->buf);
|
||||
|
||||
for (i = 0; i < 8; ++i) { /* Output full hash to temp buffer */
|
||||
store64(buffer + sizeof(S->h[i]) * i, S->h[i]);
|
||||
}
|
||||
|
||||
memcpy(out, buffer, S->outlen);
|
||||
|
||||
burn(buffer, sizeof(buffer));
|
||||
burn(S->buf, sizeof(S->buf));
|
||||
burn(S->h, sizeof(S->h));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int blake2b(void *out, const void *in, const void *key, size_t keylen)
|
||||
{
|
||||
blake2b_state S;
|
||||
|
||||
blake2b_init(&S, 64);
|
||||
my_blake2b_update(&S, in, 64);
|
||||
blake2b_final(&S, out, 64);
|
||||
burn(&S, sizeof(S));
|
||||
return 0;
|
||||
}
|
||||
|
||||
void blake2b_too(void *pout, const void *in)
|
||||
{
|
||||
uint8_t *out = (uint8_t *)pout;
|
||||
uint8_t out_buffer[64];
|
||||
uint8_t in_buffer[64];
|
||||
|
||||
blake2b_state blake_state;
|
||||
blake2b_init(&blake_state, 64);
|
||||
blake_state.buflen = blake_state.buf[1] = 4;
|
||||
my_blake2b_update(&blake_state, in, 72);
|
||||
blake2b_final(&blake_state, out_buffer, 64);
|
||||
memcpy(out, out_buffer, 32);
|
||||
out += 32;
|
||||
|
||||
register uint8_t i = 29;
|
||||
while (i--) {
|
||||
memcpy(in_buffer, out_buffer, 64);
|
||||
blake2b(out_buffer, in_buffer, NULL, 0);
|
||||
memcpy(out, out_buffer, 32);
|
||||
out += 32;
|
||||
}
|
||||
|
||||
memcpy(in_buffer, out_buffer, 64);
|
||||
blake2b(out_buffer, in_buffer, NULL, 0);
|
||||
memcpy(out, out_buffer, 64);
|
||||
|
||||
burn(&blake_state, sizeof(blake_state));
|
||||
}
|
||||
|
||||
/* Argon2 Team - Begin Code */
|
||||
int blake2b_long(void *pout, const void *in)
|
||||
{
|
||||
uint8_t *out = (uint8_t *)pout;
|
||||
blake2b_state blake_state;
|
||||
uint8_t outlen_bytes[sizeof(uint32_t)] = {0};
|
||||
|
||||
store32(outlen_bytes, 32);
|
||||
|
||||
blake2b_init(&blake_state, 32);
|
||||
my_blake2b_update(&blake_state, outlen_bytes, sizeof(outlen_bytes));
|
||||
blake2b_update(&blake_state, in, 1024);
|
||||
blake2b_final(&blake_state, out, 32);
|
||||
burn(&blake_state, sizeof(blake_state));
|
||||
return 0;
|
||||
|
||||
}
|
||||
/* Argon2 Team - End Code */
|
615
stratum/algos/ar2/core.c
Normal file
615
stratum/algos/ar2/core.c
Normal file
|
@ -0,0 +1,615 @@
|
|||
/*
|
||||
* Argon2 reference source code package - reference C implementations
|
||||
*
|
||||
* Copyright 2015
|
||||
* Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
|
||||
*
|
||||
* You may use this work under the terms of a Creative Commons CC0 1.0
|
||||
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
|
||||
* these licenses can be found at:
|
||||
*
|
||||
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* You should have received a copy of both of these licenses along with this
|
||||
* software. If not, they may be obtained at the above URLs.
|
||||
*/
|
||||
|
||||
/*For memory wiping*/
|
||||
#ifdef _MSC_VER
|
||||
#include <windows.h>
|
||||
#include <winbase.h> /* For SecureZeroMemory */
|
||||
#endif
|
||||
#if defined __STDC_LIB_EXT1__
|
||||
#define __STDC_WANT_LIB_EXT1__ 1
|
||||
#endif
|
||||
#define VC_GE_2005(version) (version >= 1400)
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "core.h"
|
||||
#include "thread.h"
|
||||
#include "../blake2/blake2.h"
|
||||
#include "../blake2/blake2-impl.h"
|
||||
|
||||
#if defined(__clang__)
|
||||
#if __has_attribute(optnone)
|
||||
#define NOT_OPTIMIZED __attribute__((optnone))
|
||||
#endif
|
||||
#elif defined(__GNUC__)
|
||||
#define GCC_VERSION \
|
||||
(__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
|
||||
#if GCC_VERSION >= 40400
|
||||
#define NOT_OPTIMIZED __attribute__((optimize("O0")))
|
||||
#endif
|
||||
#endif
|
||||
#ifndef NOT_OPTIMIZED
|
||||
#define NOT_OPTIMIZED
|
||||
#endif
|
||||
|
||||
/***************Instance and Position constructors**********/
|
||||
void init_block_value(block *b, uint8_t in) { memset(b->v, in, sizeof(b->v)); }
|
||||
|
||||
void copy_block(block *dst, const block *src) {
|
||||
memcpy(dst->v, src->v, sizeof(uint64_t) * ARGON2_QWORDS_IN_BLOCK);
|
||||
}
|
||||
|
||||
void xor_block(block *dst, const block *src) {
|
||||
int i;
|
||||
for (i = 0; i < ARGON2_QWORDS_IN_BLOCK; ++i) {
|
||||
dst->v[i] ^= src->v[i];
|
||||
}
|
||||
}
|
||||
|
||||
static void load_block(block *dst, const void *input) {
|
||||
unsigned i;
|
||||
for (i = 0; i < ARGON2_QWORDS_IN_BLOCK; ++i) {
|
||||
dst->v[i] = load64((const uint8_t *)input + i * sizeof(dst->v[i]));
|
||||
}
|
||||
}
|
||||
|
||||
static void store_block(void *output, const block *src) {
|
||||
unsigned i;
|
||||
for (i = 0; i < ARGON2_QWORDS_IN_BLOCK; ++i) {
|
||||
store64((uint8_t *)output + i * sizeof(src->v[i]), src->v[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/***************Memory functions*****************/
|
||||
|
||||
int allocate_memory(const argon2_context *context, uint8_t **memory,
|
||||
size_t num, size_t size) {
|
||||
size_t memory_size = num*size;
|
||||
if (memory == NULL) {
|
||||
return ARGON2_MEMORY_ALLOCATION_ERROR;
|
||||
}
|
||||
|
||||
/* 1. Check for multiplication overflow */
|
||||
if (size != 0 && memory_size / size != num) {
|
||||
return ARGON2_MEMORY_ALLOCATION_ERROR;
|
||||
}
|
||||
|
||||
/* 2. Try to allocate with appropriate allocator */
|
||||
if (context->allocate_cbk) {
|
||||
(context->allocate_cbk)(memory, memory_size);
|
||||
} else {
|
||||
*memory = malloc(memory_size);
|
||||
}
|
||||
|
||||
if (*memory == NULL) {
|
||||
return ARGON2_MEMORY_ALLOCATION_ERROR;
|
||||
}
|
||||
|
||||
return ARGON2_OK;
|
||||
}
|
||||
|
||||
void free_memory(const argon2_context *context, uint8_t *memory,
|
||||
size_t num, size_t size) {
|
||||
size_t memory_size = num*size;
|
||||
clear_internal_memory(memory, memory_size);
|
||||
if (context->free_cbk) {
|
||||
(context->free_cbk)(memory, memory_size);
|
||||
} else {
|
||||
free(memory);
|
||||
}
|
||||
}
|
||||
|
||||
void NOT_OPTIMIZED secure_wipe_memory(void *v, size_t n) {
|
||||
#if defined(_MSC_VER) && VC_GE_2005(_MSC_VER)
|
||||
SecureZeroMemory(v, n);
|
||||
#elif defined memset_s
|
||||
memset_s(v, n, 0, n);
|
||||
#elif defined(__OpenBSD__)
|
||||
explicit_bzero(v, n);
|
||||
#else
|
||||
static void *(*const volatile memset_sec)(void *, int, size_t) = &memset;
|
||||
memset_sec(v, 0, n);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Memory clear flag defaults to true. */
|
||||
int FLAG_clear_internal_memory = 1;
|
||||
void clear_internal_memory(void *v, size_t n) {
|
||||
if (FLAG_clear_internal_memory && v) {
|
||||
secure_wipe_memory(v, n);
|
||||
}
|
||||
}
|
||||
|
||||
void finalize(const argon2_context *context, argon2_instance_t *instance) {
|
||||
if (context != NULL && instance != NULL) {
|
||||
block blockhash;
|
||||
uint32_t l;
|
||||
|
||||
copy_block(&blockhash, instance->memory + instance->lane_length - 1);
|
||||
|
||||
/* XOR the last blocks */
|
||||
for (l = 1; l < instance->lanes; ++l) {
|
||||
uint32_t last_block_in_lane =
|
||||
l * instance->lane_length + (instance->lane_length - 1);
|
||||
xor_block(&blockhash, instance->memory + last_block_in_lane);
|
||||
}
|
||||
|
||||
/* Hash the result */
|
||||
{
|
||||
uint8_t blockhash_bytes[ARGON2_BLOCK_SIZE];
|
||||
store_block(blockhash_bytes, &blockhash);
|
||||
blake2b_long(context->out, context->outlen, blockhash_bytes,
|
||||
ARGON2_BLOCK_SIZE);
|
||||
/* clear blockhash and blockhash_bytes */
|
||||
clear_internal_memory(blockhash.v, ARGON2_BLOCK_SIZE);
|
||||
clear_internal_memory(blockhash_bytes, ARGON2_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
free_memory(context, (uint8_t *)instance->memory,
|
||||
instance->memory_blocks, sizeof(block));
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t index_alpha(const argon2_instance_t *instance,
|
||||
const argon2_position_t *position, uint32_t pseudo_rand,
|
||||
int same_lane) {
|
||||
/*
|
||||
* Pass 0:
|
||||
* This lane : all already finished segments plus already constructed
|
||||
* blocks in this segment
|
||||
* Other lanes : all already finished segments
|
||||
* Pass 1+:
|
||||
* This lane : (SYNC_POINTS - 1) last segments plus already constructed
|
||||
* blocks in this segment
|
||||
* Other lanes : (SYNC_POINTS - 1) last segments
|
||||
*/
|
||||
uint32_t reference_area_size;
|
||||
uint64_t relative_position;
|
||||
uint32_t start_position, absolute_position;
|
||||
|
||||
if (0 == position->pass) {
|
||||
/* First pass */
|
||||
if (0 == position->slice) {
|
||||
/* First slice */
|
||||
reference_area_size =
|
||||
position->index - 1; /* all but the previous */
|
||||
} else {
|
||||
if (same_lane) {
|
||||
/* The same lane => add current segment */
|
||||
reference_area_size =
|
||||
position->slice * instance->segment_length +
|
||||
position->index - 1;
|
||||
} else {
|
||||
reference_area_size =
|
||||
position->slice * instance->segment_length +
|
||||
((position->index == 0) ? (-1) : 0);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Second pass */
|
||||
if (same_lane) {
|
||||
reference_area_size = instance->lane_length -
|
||||
instance->segment_length + position->index -
|
||||
1;
|
||||
} else {
|
||||
reference_area_size = instance->lane_length -
|
||||
instance->segment_length +
|
||||
((position->index == 0) ? (-1) : 0);
|
||||
}
|
||||
}
|
||||
|
||||
/* 1.2.4. Mapping pseudo_rand to 0..<reference_area_size-1> and produce
|
||||
* relative position */
|
||||
relative_position = pseudo_rand;
|
||||
relative_position = relative_position * relative_position >> 32;
|
||||
relative_position = reference_area_size - 1 -
|
||||
(reference_area_size * relative_position >> 32);
|
||||
|
||||
/* 1.2.5 Computing starting position */
|
||||
start_position = 0;
|
||||
|
||||
if (0 != position->pass) {
|
||||
start_position = (position->slice == ARGON2_SYNC_POINTS - 1)
|
||||
? 0
|
||||
: (position->slice + 1) * instance->segment_length;
|
||||
}
|
||||
|
||||
/* 1.2.6. Computing absolute position */
|
||||
absolute_position = (start_position + relative_position) %
|
||||
instance->lane_length; /* absolute position */
|
||||
return absolute_position;
|
||||
}
|
||||
|
||||
/* Single-threaded version for p=1 case */
|
||||
static int fill_memory_blocks_st(argon2_instance_t *instance) {
|
||||
uint32_t r, s, l;
|
||||
|
||||
for (r = 0; r < instance->passes; ++r) {
|
||||
for (s = 0; s < ARGON2_SYNC_POINTS; ++s) {
|
||||
for (l = 0; l < instance->lanes; ++l) {
|
||||
argon2_position_t position = {r, l, (uint8_t)s, 0};
|
||||
fill_segment(instance, position);
|
||||
}
|
||||
}
|
||||
}
|
||||
return ARGON2_OK;
|
||||
}
|
||||
|
||||
#if !defined(ARGON2_NO_THREADS)
|
||||
|
||||
#ifdef _WIN32
|
||||
static unsigned __stdcall fill_segment_thr(void *thread_data)
|
||||
#else
|
||||
static void *fill_segment_thr(void *thread_data)
|
||||
#endif
|
||||
{
|
||||
argon2_thread_data *my_data = thread_data;
|
||||
fill_segment(my_data->instance_ptr, my_data->pos);
|
||||
argon2_thread_exit();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Multi-threaded version for p > 1 case */
|
||||
static int fill_memory_blocks_mt(argon2_instance_t *instance) {
|
||||
uint32_t r, s;
|
||||
argon2_thread_handle_t *thread = NULL;
|
||||
argon2_thread_data *thr_data = NULL;
|
||||
int rc = ARGON2_OK;
|
||||
|
||||
/* 1. Allocating space for threads */
|
||||
thread = calloc(instance->lanes, sizeof(argon2_thread_handle_t));
|
||||
if (thread == NULL) {
|
||||
rc = ARGON2_MEMORY_ALLOCATION_ERROR;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
thr_data = calloc(instance->lanes, sizeof(argon2_thread_data));
|
||||
if (thr_data == NULL) {
|
||||
rc = ARGON2_MEMORY_ALLOCATION_ERROR;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
for (r = 0; r < instance->passes; ++r) {
|
||||
for (s = 0; s < ARGON2_SYNC_POINTS; ++s) {
|
||||
uint32_t l;
|
||||
|
||||
/* 2. Calling threads */
|
||||
for (l = 0; l < instance->lanes; ++l) {
|
||||
argon2_position_t position;
|
||||
|
||||
/* 2.1 Join a thread if limit is exceeded */
|
||||
if (l >= instance->threads) {
|
||||
if (argon2_thread_join(thread[l - instance->threads])) {
|
||||
rc = ARGON2_THREAD_FAIL;
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
/* 2.2 Create thread */
|
||||
position.pass = r;
|
||||
position.lane = l;
|
||||
position.slice = (uint8_t)s;
|
||||
position.index = 0;
|
||||
thr_data[l].instance_ptr =
|
||||
instance; /* preparing the thread input */
|
||||
memcpy(&(thr_data[l].pos), &position,
|
||||
sizeof(argon2_position_t));
|
||||
if (argon2_thread_create(&thread[l], &fill_segment_thr,
|
||||
(void *)&thr_data[l])) {
|
||||
rc = ARGON2_THREAD_FAIL;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* fill_segment(instance, position); */
|
||||
/*Non-thread equivalent of the lines above */
|
||||
}
|
||||
|
||||
/* 3. Joining remaining threads */
|
||||
for (l = instance->lanes - instance->threads; l < instance->lanes;
|
||||
++l) {
|
||||
if (argon2_thread_join(thread[l])) {
|
||||
rc = ARGON2_THREAD_FAIL;
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fail:
|
||||
if (thread != NULL) {
|
||||
free(thread);
|
||||
}
|
||||
if (thr_data != NULL) {
|
||||
free(thr_data);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
#endif /* ARGON2_NO_THREADS */
|
||||
|
||||
int fill_memory_blocks(argon2_instance_t *instance) {
|
||||
if (instance == NULL || instance->lanes == 0) {
|
||||
return ARGON2_INCORRECT_PARAMETER;
|
||||
}
|
||||
#if defined(ARGON2_NO_THREADS)
|
||||
return fill_memory_blocks_st(instance);
|
||||
#else
|
||||
return instance->threads == 1 ?
|
||||
fill_memory_blocks_st(instance) : fill_memory_blocks_mt(instance);
|
||||
#endif
|
||||
}
|
||||
|
||||
int validate_inputs(const argon2_context *context) {
|
||||
if (NULL == context) {
|
||||
return ARGON2_INCORRECT_PARAMETER;
|
||||
}
|
||||
|
||||
if (NULL == context->out) {
|
||||
return ARGON2_OUTPUT_PTR_NULL;
|
||||
}
|
||||
|
||||
/* Validate output length */
|
||||
if (ARGON2_MIN_OUTLEN > context->outlen) {
|
||||
return ARGON2_OUTPUT_TOO_SHORT;
|
||||
}
|
||||
|
||||
if (ARGON2_MAX_OUTLEN < context->outlen) {
|
||||
return ARGON2_OUTPUT_TOO_LONG;
|
||||
}
|
||||
|
||||
/* Validate password (required param) */
|
||||
if (NULL == context->pwd) {
|
||||
if (0 != context->pwdlen) {
|
||||
return ARGON2_PWD_PTR_MISMATCH;
|
||||
}
|
||||
}
|
||||
|
||||
if (ARGON2_MIN_PWD_LENGTH > context->pwdlen) {
|
||||
return ARGON2_PWD_TOO_SHORT;
|
||||
}
|
||||
|
||||
if (ARGON2_MAX_PWD_LENGTH < context->pwdlen) {
|
||||
return ARGON2_PWD_TOO_LONG;
|
||||
}
|
||||
|
||||
/* Validate salt (required param) */
|
||||
if (NULL == context->salt) {
|
||||
if (0 != context->saltlen) {
|
||||
return ARGON2_SALT_PTR_MISMATCH;
|
||||
}
|
||||
}
|
||||
|
||||
if (ARGON2_MIN_SALT_LENGTH > context->saltlen) {
|
||||
return ARGON2_SALT_TOO_SHORT;
|
||||
}
|
||||
|
||||
if (ARGON2_MAX_SALT_LENGTH < context->saltlen) {
|
||||
return ARGON2_SALT_TOO_LONG;
|
||||
}
|
||||
|
||||
/* Validate secret (optional param) */
|
||||
if (NULL == context->secret) {
|
||||
if (0 != context->secretlen) {
|
||||
return ARGON2_SECRET_PTR_MISMATCH;
|
||||
}
|
||||
} else {
|
||||
if (ARGON2_MIN_SECRET > context->secretlen) {
|
||||
return ARGON2_SECRET_TOO_SHORT;
|
||||
}
|
||||
if (ARGON2_MAX_SECRET < context->secretlen) {
|
||||
return ARGON2_SECRET_TOO_LONG;
|
||||
}
|
||||
}
|
||||
|
||||
/* Validate associated data (optional param) */
|
||||
if (NULL == context->ad) {
|
||||
if (0 != context->adlen) {
|
||||
return ARGON2_AD_PTR_MISMATCH;
|
||||
}
|
||||
} else {
|
||||
if (ARGON2_MIN_AD_LENGTH > context->adlen) {
|
||||
return ARGON2_AD_TOO_SHORT;
|
||||
}
|
||||
if (ARGON2_MAX_AD_LENGTH < context->adlen) {
|
||||
return ARGON2_AD_TOO_LONG;
|
||||
}
|
||||
}
|
||||
|
||||
/* Validate memory cost */
|
||||
if (ARGON2_MIN_MEMORY > context->m_cost) {
|
||||
return ARGON2_MEMORY_TOO_LITTLE;
|
||||
}
|
||||
|
||||
if (ARGON2_MAX_MEMORY < context->m_cost) {
|
||||
return ARGON2_MEMORY_TOO_MUCH;
|
||||
}
|
||||
|
||||
if (context->m_cost < 8 * context->lanes) {
|
||||
return ARGON2_MEMORY_TOO_LITTLE;
|
||||
}
|
||||
|
||||
/* Validate time cost */
|
||||
if (ARGON2_MIN_TIME > context->t_cost) {
|
||||
return ARGON2_TIME_TOO_SMALL;
|
||||
}
|
||||
|
||||
if (ARGON2_MAX_TIME < context->t_cost) {
|
||||
return ARGON2_TIME_TOO_LARGE;
|
||||
}
|
||||
|
||||
/* Validate lanes */
|
||||
if (ARGON2_MIN_LANES > context->lanes) {
|
||||
return ARGON2_LANES_TOO_FEW;
|
||||
}
|
||||
|
||||
if (ARGON2_MAX_LANES < context->lanes) {
|
||||
return ARGON2_LANES_TOO_MANY;
|
||||
}
|
||||
|
||||
/* Validate threads */
|
||||
if (ARGON2_MIN_THREADS > context->threads) {
|
||||
return ARGON2_THREADS_TOO_FEW;
|
||||
}
|
||||
|
||||
if (ARGON2_MAX_THREADS < context->threads) {
|
||||
return ARGON2_THREADS_TOO_MANY;
|
||||
}
|
||||
|
||||
if (NULL != context->allocate_cbk && NULL == context->free_cbk) {
|
||||
return ARGON2_FREE_MEMORY_CBK_NULL;
|
||||
}
|
||||
|
||||
if (NULL == context->allocate_cbk && NULL != context->free_cbk) {
|
||||
return ARGON2_ALLOCATE_MEMORY_CBK_NULL;
|
||||
}
|
||||
|
||||
return ARGON2_OK;
|
||||
}
|
||||
|
||||
void fill_first_blocks(uint8_t *blockhash, const argon2_instance_t *instance) {
|
||||
uint32_t l;
|
||||
/* Make the first and second block in each lane as G(H0||0||i) or
|
||||
G(H0||1||i) */
|
||||
uint8_t blockhash_bytes[ARGON2_BLOCK_SIZE];
|
||||
for (l = 0; l < instance->lanes; ++l) {
|
||||
|
||||
store32(blockhash + ARGON2_PREHASH_DIGEST_LENGTH, 0);
|
||||
store32(blockhash + ARGON2_PREHASH_DIGEST_LENGTH + 4, l);
|
||||
blake2b_long(blockhash_bytes, ARGON2_BLOCK_SIZE, blockhash,
|
||||
ARGON2_PREHASH_SEED_LENGTH);
|
||||
load_block(&instance->memory[l * instance->lane_length + 0],
|
||||
blockhash_bytes);
|
||||
|
||||
store32(blockhash + ARGON2_PREHASH_DIGEST_LENGTH, 1);
|
||||
blake2b_long(blockhash_bytes, ARGON2_BLOCK_SIZE, blockhash,
|
||||
ARGON2_PREHASH_SEED_LENGTH);
|
||||
load_block(&instance->memory[l * instance->lane_length + 1],
|
||||
blockhash_bytes);
|
||||
}
|
||||
clear_internal_memory(blockhash_bytes, ARGON2_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
void initial_hash(uint8_t *blockhash, argon2_context *context,
|
||||
argon2_type type) {
|
||||
blake2b_state BlakeHash;
|
||||
uint8_t value[sizeof(uint32_t)];
|
||||
|
||||
if (NULL == context || NULL == blockhash) {
|
||||
return;
|
||||
}
|
||||
|
||||
blake2b_init(&BlakeHash, ARGON2_PREHASH_DIGEST_LENGTH);
|
||||
|
||||
store32(&value, context->lanes);
|
||||
blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
|
||||
|
||||
store32(&value, context->outlen);
|
||||
blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
|
||||
|
||||
store32(&value, context->m_cost);
|
||||
blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
|
||||
|
||||
store32(&value, context->t_cost);
|
||||
blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
|
||||
|
||||
store32(&value, ARGON2_VERSION_NUMBER);
|
||||
blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
|
||||
|
||||
store32(&value, (uint32_t)type);
|
||||
blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
|
||||
|
||||
store32(&value, context->pwdlen);
|
||||
blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
|
||||
|
||||
if (context->pwd != NULL) {
|
||||
blake2b_update(&BlakeHash, (const uint8_t *)context->pwd,
|
||||
context->pwdlen);
|
||||
|
||||
if (context->flags & ARGON2_FLAG_CLEAR_PASSWORD) {
|
||||
secure_wipe_memory(context->pwd, context->pwdlen);
|
||||
context->pwdlen = 0;
|
||||
}
|
||||
}
|
||||
|
||||
store32(&value, context->saltlen);
|
||||
blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
|
||||
|
||||
if (context->salt != NULL) {
|
||||
blake2b_update(&BlakeHash, (const uint8_t *)context->salt,
|
||||
context->saltlen);
|
||||
}
|
||||
|
||||
store32(&value, context->secretlen);
|
||||
blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
|
||||
|
||||
if (context->secret != NULL) {
|
||||
blake2b_update(&BlakeHash, (const uint8_t *)context->secret,
|
||||
context->secretlen);
|
||||
|
||||
if (context->flags & ARGON2_FLAG_CLEAR_SECRET) {
|
||||
secure_wipe_memory(context->secret, context->secretlen);
|
||||
context->secretlen = 0;
|
||||
}
|
||||
}
|
||||
|
||||
store32(&value, context->adlen);
|
||||
blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
|
||||
|
||||
if (context->ad != NULL) {
|
||||
blake2b_update(&BlakeHash, (const uint8_t *)context->ad,
|
||||
context->adlen);
|
||||
}
|
||||
|
||||
blake2b_final(&BlakeHash, blockhash, ARGON2_PREHASH_DIGEST_LENGTH);
|
||||
}
|
||||
|
||||
int initialize(argon2_instance_t *instance, argon2_context *context) {
|
||||
uint8_t blockhash[ARGON2_PREHASH_SEED_LENGTH];
|
||||
int result = ARGON2_OK;
|
||||
|
||||
if (instance == NULL || context == NULL)
|
||||
return ARGON2_INCORRECT_PARAMETER;
|
||||
instance->context_ptr = context;
|
||||
|
||||
/* 1. Memory allocation */
|
||||
result = allocate_memory(context, (uint8_t **)&(instance->memory),
|
||||
instance->memory_blocks, sizeof(block));
|
||||
if (result != ARGON2_OK) {
|
||||
return result;
|
||||
}
|
||||
|
||||
/* 2. Initial hashing */
|
||||
/* H_0 + 8 extra bytes to produce the first blocks */
|
||||
/* uint8_t blockhash[ARGON2_PREHASH_SEED_LENGTH]; */
|
||||
/* Hashing all inputs */
|
||||
initial_hash(blockhash, context, instance->type);
|
||||
/* Zeroing 8 extra bytes */
|
||||
clear_internal_memory(blockhash + ARGON2_PREHASH_DIGEST_LENGTH,
|
||||
ARGON2_PREHASH_SEED_LENGTH -
|
||||
ARGON2_PREHASH_DIGEST_LENGTH);
|
||||
|
||||
/* 3. Creating first blocks, we always have at least two blocks in a slice
|
||||
*/
|
||||
fill_first_blocks(blockhash, instance);
|
||||
/* Clearing the hash */
|
||||
clear_internal_memory(blockhash, ARGON2_PREHASH_SEED_LENGTH);
|
||||
|
||||
return ARGON2_OK;
|
||||
}
|
|
@ -1,38 +1,38 @@
|
|||
/*
|
||||
* Argon2 source code package
|
||||
* Argon2 reference source code package - reference C implementations
|
||||
*
|
||||
* Written by Daniel Dinu and Dmitry Khovratovich, 2015
|
||||
* Copyright 2015
|
||||
* Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
|
||||
*
|
||||
* This work is licensed under a Creative Commons CC0 1.0 License/Waiver.
|
||||
* You may use this work under the terms of a Creative Commons CC0 1.0
|
||||
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
|
||||
* these licenses can be found at:
|
||||
*
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along
|
||||
* with
|
||||
* this software. If not, see
|
||||
* <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* You should have received a copy of both of these licenses along with this
|
||||
* software. If not, they may be obtained at the above URLs.
|
||||
*/
|
||||
|
||||
#ifndef ARGON2_CORES_H
|
||||
#define ARGON2_CORES_H
|
||||
#ifndef ARGON2_CORE_H
|
||||
#define ARGON2_CORE_H
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#define ALIGN(n) __declspec(align(16))
|
||||
#elif defined(__GNUC__) || defined(__clang)
|
||||
#define ALIGN(x) __attribute__((__aligned__(x)))
|
||||
#else
|
||||
#define ALIGN(x)
|
||||
#endif
|
||||
#include "argon2.h"
|
||||
|
||||
/*************************Argon2 internal
|
||||
* constants**************************************************/
|
||||
#define CONST_CAST(x) (x)(uintptr_t)
|
||||
|
||||
/**********************Argon2 internal constants*******************************/
|
||||
|
||||
enum argon2_core_constants {
|
||||
/* Version of the algorithm */
|
||||
ARGON2_VERSION_NUMBER = 0x10,
|
||||
|
||||
/* Memory block size in bytes */
|
||||
ARGON2_BLOCK_SIZE = 1024,
|
||||
ARGON2_WORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 8,
|
||||
ARGON2_QWORDS_IN_BLOCK = 64,
|
||||
ARGON2_QWORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 8,
|
||||
ARGON2_OWORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 16,
|
||||
ARGON2_HWORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 32,
|
||||
ARGON2_512BIT_WORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 64,
|
||||
|
||||
/* Number of pseudo-random values generated by one call to Blake in Argon2i
|
||||
to
|
||||
|
@ -44,18 +44,14 @@ enum argon2_core_constants {
|
|||
ARGON2_PREHASH_SEED_LENGTH = 72
|
||||
};
|
||||
|
||||
/* Argon2 primitive type */
|
||||
typedef enum Argon2_type { Argon2_d = 0, Argon2_i = 1 } argon2_type;
|
||||
|
||||
/*************************Argon2 internal data
|
||||
* types**************************************************/
|
||||
/*************************Argon2 internal data types***********************/
|
||||
|
||||
/*
|
||||
* Structure for the (1KB) memory block implemented as 128 64-bit words.
|
||||
* Memory blocks can be copied, XORed. Internal words can be accessed by [] (no
|
||||
* bounds checking).
|
||||
*/
|
||||
typedef struct _block { uint64_t v[ARGON2_WORDS_IN_BLOCK]; } __attribute__ ((aligned (16))) block;
|
||||
typedef struct block_ { uint64_t v[ARGON2_QWORDS_IN_BLOCK]; } block;
|
||||
|
||||
/*****************Functions that work with the block******************/
|
||||
|
||||
|
@ -76,8 +72,16 @@ void xor_block(block *dst, const block *src);
|
|||
*/
|
||||
typedef struct Argon2_instance_t {
|
||||
block *memory; /* Memory pointer */
|
||||
uint32_t version;
|
||||
uint32_t passes; /* Number of passes */
|
||||
uint32_t memory_blocks; /* Number of blocks in memory */
|
||||
uint32_t segment_length;
|
||||
uint32_t lane_length;
|
||||
uint32_t lanes;
|
||||
uint32_t threads;
|
||||
argon2_type type;
|
||||
int print_internals; /* whether to print the memory blocks */
|
||||
argon2_context *context_ptr; /* points back to original context */
|
||||
} argon2_instance_t;
|
||||
|
||||
/*
|
||||
|
@ -97,32 +101,43 @@ typedef struct Argon2_thread_data {
|
|||
argon2_position_t pos;
|
||||
} argon2_thread_data;
|
||||
|
||||
/*************************Argon2 core
|
||||
* functions**************************************************/
|
||||
/*************************Argon2 core functions********************************/
|
||||
|
||||
/* Allocates memory to the given pointer
|
||||
/* Allocates memory to the given pointer, uses the appropriate allocator as
|
||||
* specified in the context. Total allocated memory is num*size.
|
||||
* @param context argon2_context which specifies the allocator
|
||||
* @param memory pointer to the pointer to the memory
|
||||
* @param m_cost number of blocks to allocate in the memory
|
||||
* @param size the size in bytes for each element to be allocated
|
||||
* @param num the number of elements to be allocated
|
||||
* @return ARGON2_OK if @memory is a valid pointer and memory is allocated
|
||||
*/
|
||||
int allocate_memory(block **memory, uint32_t m_cost);
|
||||
int allocate_memory(const argon2_context *context, uint8_t **memory,
|
||||
size_t num, size_t size);
|
||||
|
||||
/* Function that securely cleans the memory
|
||||
/*
|
||||
* Frees memory at the given pointer, uses the appropriate deallocator as
|
||||
* specified in the context. Also cleans the memory using clear_internal_memory.
|
||||
* @param context argon2_context which specifies the deallocator
|
||||
* @param memory pointer to buffer to be freed
|
||||
* @param size the size in bytes for each element to be deallocated
|
||||
* @param num the number of elements to be deallocated
|
||||
*/
|
||||
void free_memory(const argon2_context *context, uint8_t *memory,
|
||||
size_t num, size_t size);
|
||||
|
||||
/* Function that securely cleans the memory. This ignores any flags set
|
||||
* regarding clearing memory. Usually one just calls clear_internal_memory.
|
||||
* @param mem Pointer to the memory
|
||||
* @param s Memory size in bytes
|
||||
*/
|
||||
void secure_wipe_memory(void *v, size_t n);
|
||||
|
||||
/* Clears memory
|
||||
* @param instance pointer to the current instance
|
||||
* @param clear_memory indicates if we clear the memory with zeros.
|
||||
/* Function that securely clears the memory if FLAG_clear_internal_memory is
|
||||
* set. If the flag isn't set, this function does nothing.
|
||||
* @param mem Pointer to the memory
|
||||
* @param s Memory size in bytes
|
||||
*/
|
||||
void clear_memory(argon2_instance_t *instance, int clear);
|
||||
|
||||
/* Deallocates memory
|
||||
* @param memory pointer to the blocks
|
||||
*/
|
||||
void free_memory(block *memory);
|
||||
void clear_internal_memory(void *v, size_t n);
|
||||
|
||||
/*
|
||||
* Computes absolute position of reference block in the lane following a skewed
|
||||
|
@ -166,7 +181,7 @@ void initial_hash(uint8_t *blockhash, argon2_context *context,
|
|||
* @param blockhash Pointer to the pre-hashing digest
|
||||
* @pre blockhash must point to @a PREHASH_SEED_LENGTH allocated values
|
||||
*/
|
||||
void fill_firsts_blocks(uint8_t *blockhash, const argon2_instance_t *instance);
|
||||
void fill_first_blocks(uint8_t *blockhash, const argon2_instance_t *instance);
|
||||
|
||||
/*
|
||||
* Function allocates memory, hashes the inputs with Blake, and creates first
|
||||
|
@ -196,6 +211,7 @@ void finalize(const argon2_context *context, argon2_instance_t *instance);
|
|||
/*
|
||||
* Function that fills the segment using previous segments also from other
|
||||
* threads
|
||||
* @param context current context
|
||||
* @param instance Pointer to the current instance
|
||||
* @param position Current position
|
||||
* @pre all block pointers must be valid
|
||||
|
@ -207,14 +223,8 @@ void fill_segment(const argon2_instance_t *instance,
|
|||
* Function that fills the entire memory t_cost times based on the first two
|
||||
* blocks in each lane
|
||||
* @param instance Pointer to the current instance
|
||||
* @return ARGON2_OK if successful, @context->state
|
||||
*/
|
||||
void fill_memory_blocks(argon2_instance_t *instance);
|
||||
|
||||
/*
|
||||
* Function that performs memory-hard hashing with certain degree of parallelism
|
||||
* @param context Pointer to the Argon2 internal structure
|
||||
* @return Error code if smth is wrong, ARGON2_OK otherwise
|
||||
*/
|
||||
int argon2_core(argon2_context *context, argon2_type type);
|
||||
int fill_memory_blocks(argon2_instance_t *instance);
|
||||
|
||||
#endif
|
|
@ -1,341 +0,0 @@
|
|||
/*
|
||||
* Argon2 source code package
|
||||
*
|
||||
* Written by Daniel Dinu and Dmitry Khovratovich, 2015
|
||||
*
|
||||
* This work is licensed under a Creative Commons CC0 1.0 License/Waiver.
|
||||
*
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along
|
||||
* with
|
||||
* this software. If not, see
|
||||
* <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
*/
|
||||
|
||||
/*For memory wiping*/
|
||||
#ifdef _MSC_VER
|
||||
#include <windows.h>
|
||||
#include <winbase.h> /* For SecureZeroMemory */
|
||||
#endif
|
||||
#if defined __STDC_LIB_EXT1__
|
||||
#define __STDC_WANT_LIB_EXT1__ 1
|
||||
#endif
|
||||
#define VC_GE_2005(version) (version >= 1400)
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "argon2.h"
|
||||
#include "cores.h"
|
||||
#include "blake2/blake2.h"
|
||||
#include "blake2/blake2-impl.h"
|
||||
|
||||
#ifdef GENKAT
|
||||
#include "genkat.h"
|
||||
#endif
|
||||
|
||||
#if defined(__clang__)
|
||||
#if __has_attribute(optnone)
|
||||
#define NOT_OPTIMIZED __attribute__((optnone))
|
||||
#endif
|
||||
#elif defined(__GNUC__)
|
||||
#define GCC_VERSION \
|
||||
(__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
|
||||
#if GCC_VERSION >= 40400
|
||||
#define NOT_OPTIMIZED __attribute__((optimize("O0")))
|
||||
#endif
|
||||
#endif
|
||||
#ifndef NOT_OPTIMIZED
|
||||
#define NOT_OPTIMIZED
|
||||
#endif
|
||||
|
||||
/***************Instance and Position constructors**********/
|
||||
void init_block_value(block *b, uint8_t in) { memset(b->v, in, sizeof(b->v)); }
|
||||
|
||||
void copy_block(block *dst, const block *src) {
|
||||
memcpy(dst->v, src->v, sizeof(uint64_t) * ARGON2_WORDS_IN_BLOCK);
|
||||
}
|
||||
|
||||
void xor_block(block *dst, const block *src) {
|
||||
int i;
|
||||
for (i = 0; i < ARGON2_WORDS_IN_BLOCK; ++i) {
|
||||
dst->v[i] ^= src->v[i];
|
||||
}
|
||||
}
|
||||
|
||||
static void load_block(block *dst, const void *input) {
|
||||
unsigned i;
|
||||
for (i = 0; i < ARGON2_WORDS_IN_BLOCK; ++i) {
|
||||
dst->v[i] = load64((const uint8_t *)input + i * sizeof(dst->v[i]));
|
||||
}
|
||||
}
|
||||
|
||||
static void store_block(void *output, const block *src) {
|
||||
unsigned i;
|
||||
for (i = 0; i < ARGON2_WORDS_IN_BLOCK; ++i) {
|
||||
store64((uint8_t *)output + i * sizeof(src->v[i]), src->v[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/***************Memory allocators*****************/
|
||||
int allocate_memory(block **memory, uint32_t m_cost) {
|
||||
if (memory != NULL) {
|
||||
size_t memory_size = sizeof(block) * m_cost;
|
||||
if (m_cost != 0 &&
|
||||
memory_size / m_cost !=
|
||||
sizeof(block)) { /*1. Check for multiplication overflow*/
|
||||
return ARGON2_MEMORY_ALLOCATION_ERROR;
|
||||
}
|
||||
|
||||
*memory = (block *)malloc(memory_size); /*2. Try to allocate*/
|
||||
|
||||
if (!*memory) {
|
||||
return ARGON2_MEMORY_ALLOCATION_ERROR;
|
||||
}
|
||||
|
||||
return ARGON2_OK;
|
||||
} else {
|
||||
return ARGON2_MEMORY_ALLOCATION_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
void secure_wipe_memory(void *v, size_t n) { memset(v, 0, n); }
|
||||
|
||||
/*********Memory functions*/
|
||||
|
||||
void clear_memory(argon2_instance_t *instance, int clear) {
|
||||
if (instance->memory != NULL && clear) {
|
||||
secure_wipe_memory(instance->memory,
|
||||
sizeof(block) * /*instance->memory_blocks*/16);
|
||||
}
|
||||
}
|
||||
|
||||
void free_memory(block *memory) { free(memory); }
|
||||
|
||||
void finalize(const argon2_context *context, argon2_instance_t *instance) {
|
||||
if (context != NULL && instance != NULL) {
|
||||
block blockhash;
|
||||
copy_block(&blockhash, instance->memory + 15);
|
||||
|
||||
/* Hash the result */
|
||||
{
|
||||
uint8_t blockhash_bytes[ARGON2_BLOCK_SIZE];
|
||||
store_block(blockhash_bytes, &blockhash);
|
||||
blake2b_long(context->out, blockhash_bytes);
|
||||
secure_wipe_memory(blockhash.v, ARGON2_BLOCK_SIZE);
|
||||
secure_wipe_memory(blockhash_bytes, ARGON2_BLOCK_SIZE); /* clear blockhash_bytes */
|
||||
}
|
||||
|
||||
#ifdef GENKAT
|
||||
print_tag(context->out, context->outlen);
|
||||
#endif
|
||||
|
||||
/* Clear memory */
|
||||
clear_memory(instance, 1);
|
||||
|
||||
free_memory(instance->memory);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t index_alpha(const argon2_instance_t *instance,
|
||||
const argon2_position_t *position, uint32_t pseudo_rand,
|
||||
int same_lane) {
|
||||
/*
|
||||
* Pass 0:
|
||||
* This lane : all already finished segments plus already constructed
|
||||
* blocks in this segment
|
||||
* Other lanes : all already finished segments
|
||||
* Pass 1+:
|
||||
* This lane : (SYNC_POINTS - 1) last segments plus already constructed
|
||||
* blocks in this segment
|
||||
* Other lanes : (SYNC_POINTS - 1) last segments
|
||||
*/
|
||||
uint32_t reference_area_size;
|
||||
uint64_t relative_position;
|
||||
uint32_t start_position, absolute_position;
|
||||
|
||||
if (0 == position->pass) {
|
||||
/* First pass */
|
||||
if (0 == position->slice) {
|
||||
/* First slice */
|
||||
reference_area_size =
|
||||
position->index - 1; /* all but the previous */
|
||||
} else {
|
||||
if (same_lane) {
|
||||
/* The same lane => add current segment */
|
||||
reference_area_size =
|
||||
position->slice * 4 +
|
||||
position->index - 1;
|
||||
} else {
|
||||
reference_area_size =
|
||||
position->slice * 4 +
|
||||
((position->index == 0) ? (-1) : 0);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Second pass */
|
||||
if (same_lane) {reference_area_size = 11 + position->index;}
|
||||
else {reference_area_size = 12 - (position->index == 0);}
|
||||
}
|
||||
|
||||
/* 1.2.4. Mapping pseudo_rand to 0..<reference_area_size-1> and produce
|
||||
* relative position */
|
||||
relative_position = pseudo_rand;
|
||||
relative_position = relative_position * relative_position >> 32;
|
||||
relative_position = reference_area_size - 1 -
|
||||
(reference_area_size * relative_position >> 32);
|
||||
|
||||
/* 1.2.5 Computing starting position */
|
||||
start_position = 0;
|
||||
|
||||
if (0 != position->pass) {
|
||||
start_position = (position->slice == ARGON2_SYNC_POINTS - 1)
|
||||
? 0 : (position->slice + 1) * 4;
|
||||
}
|
||||
|
||||
/* 1.2.6. Computing absolute position */
|
||||
absolute_position = (start_position + relative_position) % 16;
|
||||
return absolute_position;
|
||||
}
|
||||
|
||||
void fill_memory_blocks(argon2_instance_t *instance) {
|
||||
uint32_t r, s;
|
||||
|
||||
for (r = 0; r < 2; ++r) {
|
||||
for (s = 0; s < ARGON2_SYNC_POINTS; ++s) {
|
||||
|
||||
argon2_position_t position;
|
||||
position.pass = r;
|
||||
position.lane = 0;
|
||||
position.slice = (uint8_t)s;
|
||||
position.index = 0;
|
||||
fill_segment(instance, position);
|
||||
}
|
||||
|
||||
#ifdef GENKAT
|
||||
internal_kat(instance, r); /* Print all memory blocks */
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void fill_first_blocks(uint8_t *blockhash, const argon2_instance_t *instance) {
|
||||
/* Make the first and second block in each lane as G(H0||i||0) or
|
||||
G(H0||i||1) */
|
||||
uint8_t blockhash_bytes[ARGON2_BLOCK_SIZE];
|
||||
store32(blockhash + ARGON2_PREHASH_DIGEST_LENGTH, 0);
|
||||
store32(blockhash + ARGON2_PREHASH_DIGEST_LENGTH + 4, 0);
|
||||
blake2b_too(blockhash_bytes, blockhash);
|
||||
load_block(&instance->memory[0], blockhash_bytes);
|
||||
|
||||
store32(blockhash + ARGON2_PREHASH_DIGEST_LENGTH, 1);
|
||||
blake2b_too(blockhash_bytes, blockhash);
|
||||
load_block(&instance->memory[1], blockhash_bytes);
|
||||
secure_wipe_memory(blockhash_bytes, ARGON2_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
|
||||
static const blake2b_state base_hash = {
|
||||
.h = {
|
||||
UINT64_C(7640891576939301192), UINT64_C(13503953896175478587),
|
||||
UINT64_C(4354685564936845355), UINT64_C(11912009170470909681),
|
||||
UINT64_C(5840696475078001361), UINT64_C(11170449401992604703),
|
||||
UINT64_C(2270897969802886507), UINT64_C(6620516959819538809)
|
||||
},
|
||||
.t = {UINT64_C(0),UINT64_C(0)},
|
||||
.f = {UINT64_C(0),UINT64_C(0)},
|
||||
.buf = {
|
||||
1, 0, 0, 0, 32, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 1, 0,
|
||||
0, 0, 32, 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, 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},
|
||||
.buflen = 28,
|
||||
.outlen = 64,
|
||||
.last_node = 0
|
||||
};
|
||||
|
||||
#define PWDLEN 32
|
||||
#define SALTLEN 32
|
||||
#define SECRETLEN 0
|
||||
#define ADLEN 0
|
||||
void initial_hash(uint8_t *blockhash, argon2_context *context,
|
||||
argon2_type type) {
|
||||
|
||||
uint8_t value[sizeof(uint32_t)];
|
||||
|
||||
/* Is it generating cache invalidation between cores ? */
|
||||
blake2b_state BlakeHash = base_hash;
|
||||
BlakeHash.buf[20] = (uint8_t) type;
|
||||
my_blake2b_update(&BlakeHash, (const uint8_t *)context->pwd,
|
||||
PWDLEN);
|
||||
|
||||
|
||||
secure_wipe_memory(context->pwd, PWDLEN);
|
||||
context->pwdlen = 0;
|
||||
|
||||
store32(&value, SALTLEN);
|
||||
my_blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
|
||||
|
||||
my_blake2b_update(&BlakeHash, (const uint8_t *)context->salt,
|
||||
SALTLEN);
|
||||
|
||||
store32(&value, SECRETLEN);
|
||||
my_blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
|
||||
|
||||
store32(&value, ADLEN);
|
||||
my_blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));
|
||||
|
||||
blake2b_final(&BlakeHash, blockhash, ARGON2_PREHASH_DIGEST_LENGTH);
|
||||
}
|
||||
|
||||
int initialize(argon2_instance_t *instance, argon2_context *context) {
|
||||
/* 1. Memory allocation */
|
||||
|
||||
|
||||
allocate_memory(&(instance->memory), 16);
|
||||
|
||||
/* 2. Initial hashing */
|
||||
/* H_0 + 8 extra bytes to produce the first blocks */
|
||||
/* Hashing all inputs */
|
||||
uint8_t blockhash[ARGON2_PREHASH_SEED_LENGTH];
|
||||
initial_hash(blockhash, context, instance->type);
|
||||
/* Zeroing 8 extra bytes */
|
||||
secure_wipe_memory(blockhash + ARGON2_PREHASH_DIGEST_LENGTH,
|
||||
ARGON2_PREHASH_SEED_LENGTH -
|
||||
ARGON2_PREHASH_DIGEST_LENGTH);
|
||||
|
||||
#ifdef GENKAT
|
||||
initial_kat(blockhash, context, instance->type);
|
||||
#endif
|
||||
|
||||
/* 3. Creating first blocks, we always have at least two blocks in a slice
|
||||
*/
|
||||
fill_first_blocks(blockhash, instance);
|
||||
/* Clearing the hash */
|
||||
secure_wipe_memory(blockhash, ARGON2_PREHASH_SEED_LENGTH);
|
||||
|
||||
return ARGON2_OK;
|
||||
}
|
||||
|
||||
int argon2_core(argon2_context *context, argon2_type type) {
|
||||
argon2_instance_t instance;
|
||||
instance.memory = NULL;
|
||||
instance.type = type;
|
||||
|
||||
/* 3. Initialization: Hashing inputs, allocating memory, filling first
|
||||
* blocks
|
||||
*/
|
||||
|
||||
int result = initialize(&instance, context);
|
||||
if (ARGON2_OK != result) return result;
|
||||
|
||||
/* 4. Filling memory */
|
||||
fill_memory_blocks(&instance);
|
||||
|
||||
/* 5. Finalization */
|
||||
finalize(context, &instance);
|
||||
|
||||
return ARGON2_OK;
|
||||
}
|
455
stratum/algos/ar2/encoding.c
Normal file
455
stratum/algos/ar2/encoding.c
Normal file
|
@ -0,0 +1,455 @@
|
|||
/*
|
||||
* Argon2 reference source code package - reference C implementations
|
||||
*
|
||||
* Copyright 2015
|
||||
* Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
|
||||
*
|
||||
* You may use this work under the terms of a Creative Commons CC0 1.0
|
||||
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
|
||||
* these licenses can be found at:
|
||||
*
|
||||
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* You should have received a copy of both of these licenses along with this
|
||||
* software. If not, they may be obtained at the above URLs.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include "encoding.h"
|
||||
#include "core.h"
|
||||
|
||||
/*
|
||||
* Example code for a decoder and encoder of "hash strings", with Argon2
|
||||
* parameters.
|
||||
*
|
||||
* This code comprises three sections:
|
||||
*
|
||||
* -- The first section contains generic Base64 encoding and decoding
|
||||
* functions. It is conceptually applicable to any hash function
|
||||
* implementation that uses Base64 to encode and decode parameters,
|
||||
* salts and outputs. It could be made into a library, provided that
|
||||
* the relevant functions are made public (non-static) and be given
|
||||
* reasonable names to avoid collisions with other functions.
|
||||
*
|
||||
* -- The second section is specific to Argon2. It encodes and decodes
|
||||
* the parameters, salts and outputs. It does not compute the hash
|
||||
* itself.
|
||||
*
|
||||
* The code was originally written by Thomas Pornin <pornin@bolet.org>,
|
||||
* to whom comments and remarks may be sent. It is released under what
|
||||
* should amount to Public Domain or its closest equivalent; the
|
||||
* following mantra is supposed to incarnate that fact with all the
|
||||
* proper legal rituals:
|
||||
*
|
||||
* ---------------------------------------------------------------------
|
||||
* This file is provided under the terms of Creative Commons CC0 1.0
|
||||
* Public Domain Dedication. To the extent possible under law, the
|
||||
* author (Thomas Pornin) has waived all copyright and related or
|
||||
* neighboring rights to this file. This work is published from: Canada.
|
||||
* ---------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (c) 2015 Thomas Pornin
|
||||
*/
|
||||
|
||||
/* ==================================================================== */
|
||||
/*
|
||||
* Common code; could be shared between different hash functions.
|
||||
*
|
||||
* Note: the Base64 functions below assume that uppercase letters (resp.
|
||||
* lowercase letters) have consecutive numerical codes, that fit on 8
|
||||
* bits. All modern systems use ASCII-compatible charsets, where these
|
||||
* properties are true. If you are stuck with a dinosaur of a system
|
||||
* that still defaults to EBCDIC then you already have much bigger
|
||||
* interoperability issues to deal with.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Some macros for constant-time comparisons. These work over values in
|
||||
* the 0..255 range. Returned value is 0x00 on "false", 0xFF on "true".
|
||||
*/
|
||||
#define EQ(x, y) ((((0U - ((unsigned)(x) ^ (unsigned)(y))) >> 8) & 0xFF) ^ 0xFF)
|
||||
#define GT(x, y) ((((unsigned)(y) - (unsigned)(x)) >> 8) & 0xFF)
|
||||
#define GE(x, y) (GT(y, x) ^ 0xFF)
|
||||
#define LT(x, y) GT(y, x)
|
||||
#define LE(x, y) GE(y, x)
|
||||
|
||||
/*
|
||||
* Convert value x (0..63) to corresponding Base64 character.
|
||||
*/
|
||||
static int b64_byte_to_char(unsigned x) {
|
||||
return (LT(x, 26) & (x + 'A')) |
|
||||
(GE(x, 26) & LT(x, 52) & (x + ('a' - 26))) |
|
||||
(GE(x, 52) & LT(x, 62) & (x + ('0' - 52))) | (EQ(x, 62) & '+') |
|
||||
(EQ(x, 63) & '/');
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert character c to the corresponding 6-bit value. If character c
|
||||
* is not a Base64 character, then 0xFF (255) is returned.
|
||||
*/
|
||||
static unsigned b64_char_to_byte(int c) {
|
||||
unsigned x;
|
||||
|
||||
x = (GE(c, 'A') & LE(c, 'Z') & (c - 'A')) |
|
||||
(GE(c, 'a') & LE(c, 'z') & (c - ('a' - 26))) |
|
||||
(GE(c, '0') & LE(c, '9') & (c - ('0' - 52))) | (EQ(c, '+') & 62) |
|
||||
(EQ(c, '/') & 63);
|
||||
return x | (EQ(x, 0) & (EQ(c, 'A') ^ 0xFF));
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert some bytes to Base64. 'dst_len' is the length (in characters)
|
||||
* of the output buffer 'dst'; if that buffer is not large enough to
|
||||
* receive the result (including the terminating 0), then (size_t)-1
|
||||
* is returned. Otherwise, the zero-terminated Base64 string is written
|
||||
* in the buffer, and the output length (counted WITHOUT the terminating
|
||||
* zero) is returned.
|
||||
*/
|
||||
static size_t to_base64(char *dst, size_t dst_len, const void *src,
|
||||
size_t src_len) {
|
||||
size_t olen;
|
||||
const unsigned char *buf;
|
||||
unsigned acc, acc_len;
|
||||
|
||||
olen = (src_len / 3) << 2;
|
||||
switch (src_len % 3) {
|
||||
case 2:
|
||||
olen++;
|
||||
/* fall through */
|
||||
case 1:
|
||||
olen += 2;
|
||||
break;
|
||||
}
|
||||
if (dst_len <= olen) {
|
||||
return (size_t)-1;
|
||||
}
|
||||
acc = 0;
|
||||
acc_len = 0;
|
||||
buf = (const unsigned char *)src;
|
||||
while (src_len-- > 0) {
|
||||
acc = (acc << 8) + (*buf++);
|
||||
acc_len += 8;
|
||||
while (acc_len >= 6) {
|
||||
acc_len -= 6;
|
||||
*dst++ = (char)b64_byte_to_char((acc >> acc_len) & 0x3F);
|
||||
}
|
||||
}
|
||||
if (acc_len > 0) {
|
||||
*dst++ = (char)b64_byte_to_char((acc << (6 - acc_len)) & 0x3F);
|
||||
}
|
||||
*dst++ = 0;
|
||||
return olen;
|
||||
}
|
||||
|
||||
/*
|
||||
* Decode Base64 chars into bytes. The '*dst_len' value must initially
|
||||
* contain the length of the output buffer '*dst'; when the decoding
|
||||
* ends, the actual number of decoded bytes is written back in
|
||||
* '*dst_len'.
|
||||
*
|
||||
* Decoding stops when a non-Base64 character is encountered, or when
|
||||
* the output buffer capacity is exceeded. If an error occurred (output
|
||||
* buffer is too small, invalid last characters leading to unprocessed
|
||||
* buffered bits), then NULL is returned; otherwise, the returned value
|
||||
* points to the first non-Base64 character in the source stream, which
|
||||
* may be the terminating zero.
|
||||
*/
|
||||
static const char *from_base64(void *dst, size_t *dst_len, const char *src) {
|
||||
size_t len;
|
||||
unsigned char *buf;
|
||||
unsigned acc, acc_len;
|
||||
|
||||
buf = (unsigned char *)dst;
|
||||
len = 0;
|
||||
acc = 0;
|
||||
acc_len = 0;
|
||||
for (;;) {
|
||||
unsigned d;
|
||||
|
||||
d = b64_char_to_byte(*src);
|
||||
if (d == 0xFF) {
|
||||
break;
|
||||
}
|
||||
src++;
|
||||
acc = (acc << 6) + d;
|
||||
acc_len += 6;
|
||||
if (acc_len >= 8) {
|
||||
acc_len -= 8;
|
||||
if ((len++) >= *dst_len) {
|
||||
return NULL;
|
||||
}
|
||||
*buf++ = (acc >> acc_len) & 0xFF;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If the input length is equal to 1 modulo 4 (which is
|
||||
* invalid), then there will remain 6 unprocessed bits;
|
||||
* otherwise, only 0, 2 or 4 bits are buffered. The buffered
|
||||
* bits must also all be zero.
|
||||
*/
|
||||
if (acc_len > 4 || (acc & (((unsigned)1 << acc_len) - 1)) != 0) {
|
||||
return NULL;
|
||||
}
|
||||
*dst_len = len;
|
||||
return src;
|
||||
}
|
||||
|
||||
/*
|
||||
* Decode decimal integer from 'str'; the value is written in '*v'.
|
||||
* Returned value is a pointer to the next non-decimal character in the
|
||||
* string. If there is no digit at all, or the value encoding is not
|
||||
* minimal (extra leading zeros), or the value does not fit in an
|
||||
* 'unsigned long', then NULL is returned.
|
||||
*/
|
||||
static const char *decode_decimal(const char *str, unsigned long *v) {
|
||||
const char *orig;
|
||||
unsigned long acc;
|
||||
|
||||
acc = 0;
|
||||
for (orig = str;; str++) {
|
||||
int c;
|
||||
|
||||
c = *str;
|
||||
if (c < '0' || c > '9') {
|
||||
break;
|
||||
}
|
||||
c -= '0';
|
||||
if (acc > (ULONG_MAX / 10)) {
|
||||
return NULL;
|
||||
}
|
||||
acc *= 10;
|
||||
if ((unsigned long)c > (ULONG_MAX - acc)) {
|
||||
return NULL;
|
||||
}
|
||||
acc += (unsigned long)c;
|
||||
}
|
||||
if (str == orig || (*orig == '0' && str != (orig + 1))) {
|
||||
return NULL;
|
||||
}
|
||||
*v = acc;
|
||||
return str;
|
||||
}
|
||||
|
||||
/* ==================================================================== */
|
||||
/*
|
||||
* Code specific to Argon2.
|
||||
*
|
||||
* The code below applies the following format:
|
||||
*
|
||||
* $argon2<T>[$v=<num>]$m=<num>,t=<num>,p=<num>$<bin>$<bin>
|
||||
*
|
||||
* where <T> is either 'd', 'id', or 'i', <num> is a decimal integer (positive,
|
||||
* fits in an 'unsigned long'), and <bin> is Base64-encoded data (no '=' padding
|
||||
* characters, no newline or whitespace).
|
||||
*
|
||||
* The last two binary chunks (encoded in Base64) are, in that order,
|
||||
* the salt and the output. Both are required. The binary salt length and the
|
||||
* output length must be in the allowed ranges defined in argon2.h.
|
||||
*
|
||||
* The ctx struct must contain buffers large enough to hold the salt and pwd
|
||||
* when it is fed into decode_string.
|
||||
*/
|
||||
|
||||
int decode_string(argon2_context *ctx, const char *str, argon2_type type) {
|
||||
|
||||
/* check for prefix */
|
||||
#define CC(prefix) \
|
||||
do { \
|
||||
size_t cc_len = strlen(prefix); \
|
||||
if (strncmp(str, prefix, cc_len) != 0) { \
|
||||
return ARGON2_DECODING_FAIL; \
|
||||
} \
|
||||
str += cc_len; \
|
||||
} while ((void)0, 0)
|
||||
|
||||
/* optional prefix checking with supplied code */
|
||||
#define CC_opt(prefix, code) \
|
||||
do { \
|
||||
size_t cc_len = strlen(prefix); \
|
||||
if (strncmp(str, prefix, cc_len) == 0) { \
|
||||
str += cc_len; \
|
||||
{ code; } \
|
||||
} \
|
||||
} while ((void)0, 0)
|
||||
|
||||
/* Decoding prefix into decimal */
|
||||
#define DECIMAL(x) \
|
||||
do { \
|
||||
unsigned long dec_x; \
|
||||
str = decode_decimal(str, &dec_x); \
|
||||
if (str == NULL) { \
|
||||
return ARGON2_DECODING_FAIL; \
|
||||
} \
|
||||
(x) = dec_x; \
|
||||
} while ((void)0, 0)
|
||||
|
||||
|
||||
/* Decoding prefix into uint32_t decimal */
|
||||
#define DECIMAL_U32(x) \
|
||||
do { \
|
||||
unsigned long dec_x; \
|
||||
str = decode_decimal(str, &dec_x); \
|
||||
if (str == NULL || dec_x > UINT32_MAX) { \
|
||||
return ARGON2_DECODING_FAIL; \
|
||||
} \
|
||||
(x) = (uint32_t)dec_x; \
|
||||
} while ((void)0, 0)
|
||||
|
||||
|
||||
/* Decoding base64 into a binary buffer */
|
||||
#define BIN(buf, max_len, len) \
|
||||
do { \
|
||||
size_t bin_len = (max_len); \
|
||||
str = from_base64(buf, &bin_len, str); \
|
||||
if (str == NULL || bin_len > UINT32_MAX) { \
|
||||
return ARGON2_DECODING_FAIL; \
|
||||
} \
|
||||
(len) = (uint32_t)bin_len; \
|
||||
} while ((void)0, 0)
|
||||
|
||||
size_t maxsaltlen = ctx->saltlen;
|
||||
size_t maxoutlen = ctx->outlen;
|
||||
int validation_result;
|
||||
const char* type_string;
|
||||
|
||||
/* We should start with the argon2_type we are using */
|
||||
type_string = argon2_type2string(type, 0);
|
||||
if (!type_string) {
|
||||
return ARGON2_INCORRECT_TYPE;
|
||||
}
|
||||
|
||||
CC("$");
|
||||
CC(type_string);
|
||||
|
||||
CC("$m=");
|
||||
DECIMAL_U32(ctx->m_cost);
|
||||
CC(",t=");
|
||||
DECIMAL_U32(ctx->t_cost);
|
||||
CC(",p=");
|
||||
DECIMAL_U32(ctx->lanes);
|
||||
ctx->threads = ctx->lanes;
|
||||
|
||||
CC("$");
|
||||
BIN(ctx->salt, maxsaltlen, ctx->saltlen);
|
||||
CC("$");
|
||||
BIN(ctx->out, maxoutlen, ctx->outlen);
|
||||
|
||||
/* The rest of the fields get the default values */
|
||||
ctx->secret = NULL;
|
||||
ctx->secretlen = 0;
|
||||
ctx->ad = NULL;
|
||||
ctx->adlen = 0;
|
||||
ctx->allocate_cbk = NULL;
|
||||
ctx->free_cbk = NULL;
|
||||
ctx->flags = ARGON2_DEFAULT_FLAGS;
|
||||
|
||||
/* On return, must have valid context */
|
||||
validation_result = validate_inputs(ctx);
|
||||
if (validation_result != ARGON2_OK) {
|
||||
return validation_result;
|
||||
}
|
||||
|
||||
/* Can't have any additional characters */
|
||||
if (*str == 0) {
|
||||
return ARGON2_OK;
|
||||
} else {
|
||||
return ARGON2_DECODING_FAIL;
|
||||
}
|
||||
#undef CC
|
||||
#undef CC_opt
|
||||
#undef DECIMAL
|
||||
#undef BIN
|
||||
}
|
||||
|
||||
int encode_string(char *dst, size_t dst_len, argon2_context *ctx,
|
||||
argon2_type type) {
|
||||
#define SS(str) \
|
||||
do { \
|
||||
size_t pp_len = strlen(str); \
|
||||
if (pp_len >= dst_len) { \
|
||||
return ARGON2_ENCODING_FAIL; \
|
||||
} \
|
||||
memcpy(dst, str, pp_len + 1); \
|
||||
dst += pp_len; \
|
||||
dst_len -= pp_len; \
|
||||
} while ((void)0, 0)
|
||||
|
||||
#define SX(x) \
|
||||
do { \
|
||||
char tmp[30]; \
|
||||
sprintf(tmp, "%lu", (unsigned long)(x)); \
|
||||
SS(tmp); \
|
||||
} while ((void)0, 0)
|
||||
|
||||
#define SB(buf, len) \
|
||||
do { \
|
||||
size_t sb_len = to_base64(dst, dst_len, buf, len); \
|
||||
if (sb_len == (size_t)-1) { \
|
||||
return ARGON2_ENCODING_FAIL; \
|
||||
} \
|
||||
dst += sb_len; \
|
||||
dst_len -= sb_len; \
|
||||
} while ((void)0, 0)
|
||||
|
||||
const char* type_string = argon2_type2string(type, 0);
|
||||
int validation_result = validate_inputs(ctx);
|
||||
|
||||
if (!type_string) {
|
||||
return ARGON2_ENCODING_FAIL;
|
||||
}
|
||||
|
||||
if (validation_result != ARGON2_OK) {
|
||||
return validation_result;
|
||||
}
|
||||
|
||||
|
||||
SS("$");
|
||||
SS(type_string);
|
||||
|
||||
SS("$m=");
|
||||
SX(ctx->m_cost);
|
||||
SS(",t=");
|
||||
SX(ctx->t_cost);
|
||||
SS(",p=");
|
||||
SX(ctx->lanes);
|
||||
|
||||
SS("$");
|
||||
SB(ctx->salt, ctx->saltlen);
|
||||
|
||||
SS("$");
|
||||
SB(ctx->out, ctx->outlen);
|
||||
return ARGON2_OK;
|
||||
|
||||
#undef SS
|
||||
#undef SX
|
||||
#undef SB
|
||||
}
|
||||
|
||||
size_t b64len(uint32_t len) {
|
||||
size_t olen = ((size_t)len / 3) << 2;
|
||||
|
||||
switch (len % 3) {
|
||||
case 2:
|
||||
olen++;
|
||||
/* fall through */
|
||||
case 1:
|
||||
olen += 2;
|
||||
break;
|
||||
}
|
||||
|
||||
return olen;
|
||||
}
|
||||
|
||||
size_t numlen(uint32_t num) {
|
||||
size_t len = 1;
|
||||
while (num >= 10) {
|
||||
++len;
|
||||
num = num / 10;
|
||||
}
|
||||
return len;
|
||||
}
|
57
stratum/algos/ar2/encoding.h
Normal file
57
stratum/algos/ar2/encoding.h
Normal file
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Argon2 reference source code package - reference C implementations
|
||||
*
|
||||
* Copyright 2015
|
||||
* Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
|
||||
*
|
||||
* You may use this work under the terms of a Creative Commons CC0 1.0
|
||||
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
|
||||
* these licenses can be found at:
|
||||
*
|
||||
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* You should have received a copy of both of these licenses along with this
|
||||
* software. If not, they may be obtained at the above URLs.
|
||||
*/
|
||||
|
||||
#ifndef ENCODING_H
|
||||
#define ENCODING_H
|
||||
#include "argon2.h"
|
||||
|
||||
#define ARGON2_MAX_DECODED_LANES UINT32_C(255)
|
||||
#define ARGON2_MIN_DECODED_SALT_LEN UINT32_C(8)
|
||||
#define ARGON2_MIN_DECODED_OUT_LEN UINT32_C(12)
|
||||
|
||||
/*
|
||||
* encode an Argon2 hash string into the provided buffer. 'dst_len'
|
||||
* contains the size, in characters, of the 'dst' buffer; if 'dst_len'
|
||||
* is less than the number of required characters (including the
|
||||
* terminating 0), then this function returns ARGON2_ENCODING_ERROR.
|
||||
*
|
||||
* on success, ARGON2_OK is returned.
|
||||
*/
|
||||
int encode_string(char *dst, size_t dst_len, argon2_context *ctx,
|
||||
argon2_type type);
|
||||
|
||||
/*
|
||||
* Decodes an Argon2 hash string into the provided structure 'ctx'.
|
||||
* The only fields that must be set prior to this call are ctx.saltlen and
|
||||
* ctx.outlen (which must be the maximal salt and out length values that are
|
||||
* allowed), ctx.salt and ctx.out (which must be buffers of the specified
|
||||
* length), and ctx.pwd and ctx.pwdlen which must hold a valid password.
|
||||
*
|
||||
* Invalid input string causes an error. On success, the ctx is valid and all
|
||||
* fields have been initialized.
|
||||
*
|
||||
* Returned value is ARGON2_OK on success, other ARGON2_ codes on error.
|
||||
*/
|
||||
int decode_string(argon2_context *ctx, const char *str, argon2_type type);
|
||||
|
||||
/* Returns the length of the encoded byte stream with length len */
|
||||
size_t b64len(uint32_t len);
|
||||
|
||||
/* Returns the length of the encoded number num */
|
||||
size_t numlen(uint32_t num);
|
||||
|
||||
#endif
|
|
@ -1,182 +0,0 @@
|
|||
#include <inttypes.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "argon2.h"
|
||||
#include "cores.h"
|
||||
|
||||
void initial_kat(const uint8_t *blockhash, const argon2_context *context,
|
||||
argon2_type type) {
|
||||
unsigned i;
|
||||
|
||||
if (blockhash != NULL && context != NULL) {
|
||||
printf("=======================================");
|
||||
|
||||
switch (type) {
|
||||
case Argon2_d:
|
||||
printf("Argon2d\n");
|
||||
break;
|
||||
|
||||
case Argon2_i:
|
||||
printf("Argon2i\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
printf("Memory: %u KiB, Iterations: %u, Parallelism: %u lanes, Tag "
|
||||
"length: %u bytes\n",
|
||||
context->m_cost, context->t_cost, context->lanes,
|
||||
context->outlen);
|
||||
|
||||
printf("Password[%u]: ", context->pwdlen);
|
||||
|
||||
if (context->flags & ARGON2_FLAG_CLEAR_PASSWORD) {
|
||||
printf("CLEARED\n");
|
||||
} else {
|
||||
for (i = 0; i < context->pwdlen; ++i) {
|
||||
printf("%2.2x ", ((unsigned char *)context->pwd)[i]);
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
printf("Salt[%u]: ", context->saltlen);
|
||||
|
||||
for (i = 0; i < context->saltlen; ++i) {
|
||||
printf("%2.2x ", ((unsigned char *)context->salt)[i]);
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
|
||||
printf("Secret[%u]: ", context->secretlen);
|
||||
|
||||
if (context->flags & ARGON2_FLAG_CLEAR_SECRET) {
|
||||
printf("CLEARED\n");
|
||||
} else {
|
||||
for (i = 0; i < context->secretlen; ++i) {
|
||||
printf("%2.2x ", ((unsigned char *)context->secret)[i]);
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
printf("Associated data[%u]: ", context->adlen);
|
||||
|
||||
for (i = 0; i < context->adlen; ++i) {
|
||||
printf("%2.2x ", ((unsigned char *)context->ad)[i]);
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
|
||||
printf("Pre-hashing digest: ");
|
||||
|
||||
for (i = 0; i < ARGON2_PREHASH_DIGEST_LENGTH; ++i) {
|
||||
printf("%2.2x ", ((unsigned char *)blockhash)[i]);
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
void print_tag(const void *out, uint32_t outlen) {
|
||||
unsigned i;
|
||||
if (out != NULL) {
|
||||
printf("Tag: ");
|
||||
|
||||
for (i = 0; i < outlen; ++i) {
|
||||
printf("%2.2x ", ((uint8_t *)out)[i]);
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
void internal_kat(const argon2_instance_t *instance, uint32_t pass) {
|
||||
|
||||
if (instance != NULL) {
|
||||
uint32_t i, j;
|
||||
printf("\n After pass %u:\n", pass);
|
||||
|
||||
for (i = 0; i < instance->memory_blocks; ++i) {
|
||||
uint32_t how_many_words =
|
||||
(instance->memory_blocks > ARGON2_WORDS_IN_BLOCK)
|
||||
? 1
|
||||
: ARGON2_WORDS_IN_BLOCK;
|
||||
|
||||
for (j = 0; j < how_many_words; ++j)
|
||||
printf("Block %.4u [%3u]: %016" PRIx64 "\n", i, j,
|
||||
instance->memory[i].v[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void fatal(const char *error) {
|
||||
fprintf(stderr, "Error: %s\n", error);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static void generate_testvectors(const char *type) {
|
||||
#define TEST_OUTLEN 32
|
||||
#define TEST_PWDLEN 32
|
||||
#define TEST_SALTLEN 16
|
||||
#define TEST_SECRETLEN 8
|
||||
#define TEST_ADLEN 12
|
||||
argon2_context context;
|
||||
|
||||
unsigned char out[TEST_OUTLEN];
|
||||
unsigned char pwd[TEST_PWDLEN];
|
||||
unsigned char salt[TEST_SALTLEN];
|
||||
unsigned char secret[TEST_SECRETLEN];
|
||||
unsigned char ad[TEST_ADLEN];
|
||||
const allocate_fptr myown_allocator = NULL;
|
||||
const deallocate_fptr myown_deallocator = NULL;
|
||||
|
||||
unsigned t_cost = 3;
|
||||
unsigned m_cost = 16;
|
||||
unsigned lanes = 4;
|
||||
|
||||
memset(pwd, 1, TEST_OUTLEN);
|
||||
memset(salt, 2, TEST_SALTLEN);
|
||||
memset(secret, 3, TEST_SECRETLEN);
|
||||
memset(ad, 4, TEST_ADLEN);
|
||||
|
||||
context.out = out;
|
||||
context.outlen = TEST_OUTLEN;
|
||||
context.pwd = pwd;
|
||||
context.pwdlen = TEST_PWDLEN;
|
||||
context.salt = salt;
|
||||
context.saltlen = TEST_SALTLEN;
|
||||
context.secret = secret;
|
||||
context.secretlen = TEST_SECRETLEN;
|
||||
context.ad = ad;
|
||||
context.adlen = TEST_ADLEN;
|
||||
context.t_cost = t_cost;
|
||||
context.m_cost = m_cost;
|
||||
context.lanes = lanes;
|
||||
context.threads = lanes;
|
||||
context.allocate_cbk = myown_allocator;
|
||||
context.free_cbk = myown_deallocator;
|
||||
context.flags = 0;
|
||||
|
||||
#undef TEST_OUTLEN
|
||||
#undef TEST_PWDLEN
|
||||
#undef TEST_SALTLEN
|
||||
#undef TEST_SECRETLEN
|
||||
#undef TEST_ADLEN
|
||||
|
||||
if (!strcmp(type, "d")) {
|
||||
argon2d(&context);
|
||||
} else if (!strcmp(type, "i")) {
|
||||
argon2i(&context);
|
||||
} else
|
||||
fatal("wrong Argon2 type");
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
const char *type = (argc > 1) ? argv[1] : "i";
|
||||
generate_testvectors(type);
|
||||
return ARGON2_OK;
|
||||
}
|
|
@ -1,45 +0,0 @@
|
|||
/*
|
||||
* Argon2 source code package
|
||||
*
|
||||
* Written by Daniel Dinu and Dmitry Khovratovich, 2015
|
||||
*
|
||||
* This work is licensed under a Creative Commons CC0 1.0 License/Waiver.
|
||||
*
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along
|
||||
* with
|
||||
* this software. If not, see
|
||||
* <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
*/
|
||||
|
||||
#ifndef ARGON2_KAT_H
|
||||
#define ARGON2_KAT_H
|
||||
|
||||
/*
|
||||
* Initial KAT function that prints the inputs to the file
|
||||
* @param blockhash Array that contains pre-hashing digest
|
||||
* @param context Holds inputs
|
||||
* @param type Argon2 type
|
||||
* @pre blockhash must point to INPUT_INITIAL_HASH_LENGTH bytes
|
||||
* @pre context member pointers must point to allocated memory of size according
|
||||
* to the length values
|
||||
*/
|
||||
void initial_kat(const uint8_t *blockhash, const argon2_context *context,
|
||||
argon2_type type);
|
||||
|
||||
/*
|
||||
* Function that prints the output tag
|
||||
* @param out output array pointer
|
||||
* @param outlen digest length
|
||||
* @pre out must point to @a outlen bytes
|
||||
**/
|
||||
void print_tag(const void *out, uint32_t outlen);
|
||||
|
||||
/*
|
||||
* Function that prints the internal state at given moment
|
||||
* @param instance pointer to the current instance
|
||||
* @param pass current pass number
|
||||
* @pre instance must have necessary memory allocated
|
||||
**/
|
||||
void internal_kat(const argon2_instance_t *instance, uint32_t pass);
|
||||
|
||||
#endif
|
|
@ -1,150 +1,214 @@
|
|||
/*
|
||||
* Argon2 source code package
|
||||
* Argon2 reference source code package - reference C implementations
|
||||
*
|
||||
* Written by Daniel Dinu and Dmitry Khovratovich, 2015
|
||||
* Copyright 2015
|
||||
* Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
|
||||
*
|
||||
* This work is licensed under a Creative Commons CC0 1.0 License/Waiver.
|
||||
* You may use this work under the terms of a Creative Commons CC0 1.0
|
||||
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
|
||||
* these licenses can be found at:
|
||||
*
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along
|
||||
* with
|
||||
* this software. If not, see
|
||||
* <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* You should have received a copy of both of these licenses along with this
|
||||
* software. If not, they may be obtained at the above URLs.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include <immintrin.h>
|
||||
|
||||
#include "argon2.h"
|
||||
#include "cores.h"
|
||||
#include "opt.h"
|
||||
#include "core.h"
|
||||
|
||||
#include "blake2/blake2.h"
|
||||
#include "blake2/blamka-round-opt.h"
|
||||
#include "../blake2/blake2.h"
|
||||
#include "../blake2/blamka-round-opt.h"
|
||||
|
||||
void fill_block(__m128i *state, __m128i const *ref_block, __m128i *next_block)
|
||||
{
|
||||
__m128i block_XY[ARGON2_QWORDS_IN_BLOCK] __attribute__ ((aligned (16)));
|
||||
uint32_t i;
|
||||
for (i = 0; i < ARGON2_QWORDS_IN_BLOCK; i++) {
|
||||
block_XY[i] = state[i] = _mm_xor_si128(
|
||||
state[i], _mm_load_si128(&ref_block[i]));
|
||||
/*
|
||||
* Function fills a new memory block and optionally XORs the old block over the new one.
|
||||
* Memory must be initialized.
|
||||
* @param state Pointer to the just produced block. Content will be updated(!)
|
||||
* @param ref_block Pointer to the reference block
|
||||
* @param next_block Pointer to the block to be XORed over. May coincide with @ref_block
|
||||
* @param with_xor Whether to XOR into the new block (1) or just overwrite (0)
|
||||
* @pre all block pointers must be valid
|
||||
*/
|
||||
#if defined(__AVX512F__)
|
||||
static void fill_block(__m512i *state, const block *ref_block,
|
||||
block *next_block, int with_xor) {
|
||||
__m512i block_XY[ARGON2_512BIT_WORDS_IN_BLOCK];
|
||||
unsigned int i;
|
||||
|
||||
if (with_xor) {
|
||||
for (i = 0; i < ARGON2_512BIT_WORDS_IN_BLOCK; i++) {
|
||||
state[i] = _mm512_xor_si512(
|
||||
state[i], _mm512_loadu_si512((const __m512i *)ref_block->v + i));
|
||||
block_XY[i] = _mm512_xor_si512(
|
||||
state[i], _mm512_loadu_si512((const __m512i *)next_block->v + i));
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < ARGON2_512BIT_WORDS_IN_BLOCK; i++) {
|
||||
block_XY[i] = state[i] = _mm512_xor_si512(
|
||||
state[i], _mm512_loadu_si512((const __m512i *)ref_block->v + i));
|
||||
}
|
||||
}
|
||||
|
||||
BLAKE2_ROUND(state[0], state[1], state[2], state[3], state[4], state[5], state[6], state[7]);
|
||||
BLAKE2_ROUND(state[8], state[9], state[10], state[11], state[12], state[13], state[14], state[15]);
|
||||
BLAKE2_ROUND(state[16], state[17], state[18], state[19], state[20], state[21], state[22], state[23]);
|
||||
BLAKE2_ROUND(state[24], state[25], state[26], state[27], state[28], state[29], state[30], state[31]);
|
||||
BLAKE2_ROUND(state[32], state[33], state[34], state[35], state[36], state[37], state[38], state[39]);
|
||||
BLAKE2_ROUND(state[40], state[41], state[42], state[43], state[44], state[45], state[46], state[47]);
|
||||
BLAKE2_ROUND(state[48], state[49], state[50], state[51], state[52], state[53], state[54], state[55]);
|
||||
BLAKE2_ROUND(state[56], state[57], state[58], state[59], state[60], state[61], state[62], state[63]);
|
||||
/*for (i = 0; i < 8; ++i) {
|
||||
for (i = 0; i < 2; ++i) {
|
||||
BLAKE2_ROUND_1(
|
||||
state[8 * i + 0], state[8 * i + 1], state[8 * i + 2], state[8 * i + 3],
|
||||
state[8 * i + 4], state[8 * i + 5], state[8 * i + 6], state[8 * i + 7]);
|
||||
}
|
||||
|
||||
for (i = 0; i < 2; ++i) {
|
||||
BLAKE2_ROUND_2(
|
||||
state[2 * 0 + i], state[2 * 1 + i], state[2 * 2 + i], state[2 * 3 + i],
|
||||
state[2 * 4 + i], state[2 * 5 + i], state[2 * 6 + i], state[2 * 7 + i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < ARGON2_512BIT_WORDS_IN_BLOCK; i++) {
|
||||
state[i] = _mm512_xor_si512(state[i], block_XY[i]);
|
||||
_mm512_storeu_si512((__m512i *)next_block->v + i, state[i]);
|
||||
}
|
||||
}
|
||||
#elif defined(__AVX2__)
|
||||
static void fill_block(__m256i *state, const block *ref_block,
|
||||
block *next_block, int with_xor) {
|
||||
__m256i block_XY[ARGON2_HWORDS_IN_BLOCK];
|
||||
unsigned int i;
|
||||
|
||||
if (with_xor) {
|
||||
for (i = 0; i < ARGON2_HWORDS_IN_BLOCK; i++) {
|
||||
state[i] = _mm256_xor_si256(
|
||||
state[i], _mm256_loadu_si256((const __m256i *)ref_block->v + i));
|
||||
block_XY[i] = _mm256_xor_si256(
|
||||
state[i], _mm256_loadu_si256((const __m256i *)next_block->v + i));
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < ARGON2_HWORDS_IN_BLOCK; i++) {
|
||||
block_XY[i] = state[i] = _mm256_xor_si256(
|
||||
state[i], _mm256_loadu_si256((const __m256i *)ref_block->v + i));
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; ++i) {
|
||||
BLAKE2_ROUND_1(state[8 * i + 0], state[8 * i + 4], state[8 * i + 1], state[8 * i + 5],
|
||||
state[8 * i + 2], state[8 * i + 6], state[8 * i + 3], state[8 * i + 7]);
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; ++i) {
|
||||
BLAKE2_ROUND_2(state[ 0 + i], state[ 4 + i], state[ 8 + i], state[12 + i],
|
||||
state[16 + i], state[20 + i], state[24 + i], state[28 + i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < ARGON2_HWORDS_IN_BLOCK; i++) {
|
||||
state[i] = _mm256_xor_si256(state[i], block_XY[i]);
|
||||
_mm256_storeu_si256((__m256i *)next_block->v + i, state[i]);
|
||||
}
|
||||
}
|
||||
#else
|
||||
static void fill_block(__m128i *state, const block *ref_block,
|
||||
block *next_block, int with_xor) {
|
||||
__m128i block_XY[ARGON2_OWORDS_IN_BLOCK];
|
||||
unsigned int i;
|
||||
|
||||
if (with_xor) {
|
||||
for (i = 0; i < ARGON2_OWORDS_IN_BLOCK; i++) {
|
||||
state[i] = _mm_xor_si128(
|
||||
state[i], _mm_loadu_si128((const __m128i *)ref_block->v + i));
|
||||
block_XY[i] = _mm_xor_si128(
|
||||
state[i], _mm_loadu_si128((const __m128i *)next_block->v + i));
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < ARGON2_OWORDS_IN_BLOCK; i++) {
|
||||
block_XY[i] = state[i] = _mm_xor_si128(
|
||||
state[i], _mm_loadu_si128((const __m128i *)ref_block->v + i));
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 8; ++i) {
|
||||
BLAKE2_ROUND(state[8 * i + 0], state[8 * i + 1], state[8 * i + 2],
|
||||
state[8 * i + 3], state[8 * i + 4], state[8 * i + 5],
|
||||
state[8 * i + 6], state[8 * i + 7]);
|
||||
}*/
|
||||
state[8 * i + 3], state[8 * i + 4], state[8 * i + 5],
|
||||
state[8 * i + 6], state[8 * i + 7]);
|
||||
}
|
||||
|
||||
BLAKE2_ROUND(state[0], state[8], state[16], state[24], state[32], state[40], state[48], state[56]);
|
||||
BLAKE2_ROUND(state[1], state[9], state[17], state[25], state[33], state[41], state[49], state[57]);
|
||||
BLAKE2_ROUND(state[2], state[10], state[18], state[26], state[34], state[42], state[50], state[58]);
|
||||
BLAKE2_ROUND(state[3], state[11], state[19], state[27], state[35], state[43], state[51], state[59]);
|
||||
BLAKE2_ROUND(state[4], state[12], state[20], state[28], state[36], state[44], state[52], state[60]);
|
||||
BLAKE2_ROUND(state[5], state[13], state[21], state[29], state[37], state[45], state[53], state[61]);
|
||||
BLAKE2_ROUND(state[6], state[14], state[22], state[30], state[38], state[46], state[54], state[62]);
|
||||
BLAKE2_ROUND(state[7], state[15], state[23], state[31], state[39], state[47], state[55], state[63]);
|
||||
/*for (i = 0; i < 8; ++i) {
|
||||
for (i = 0; i < 8; ++i) {
|
||||
BLAKE2_ROUND(state[8 * 0 + i], state[8 * 1 + i], state[8 * 2 + i],
|
||||
state[8 * 3 + i], state[8 * 4 + i], state[8 * 5 + i],
|
||||
state[8 * 6 + i], state[8 * 7 + i]);
|
||||
}*/
|
||||
state[8 * 3 + i], state[8 * 4 + i], state[8 * 5 + i],
|
||||
state[8 * 6 + i], state[8 * 7 + i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < ARGON2_QWORDS_IN_BLOCK; i++) {
|
||||
for (i = 0; i < ARGON2_OWORDS_IN_BLOCK; i++) {
|
||||
state[i] = _mm_xor_si128(state[i], block_XY[i]);
|
||||
_mm_storeu_si128(&next_block[i], state[i]);
|
||||
_mm_storeu_si128((__m128i *)next_block->v + i, state[i]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static const uint64_t bad_rands[32] = {
|
||||
UINT64_C(17023632018251376180), UINT64_C(4911461131397773491),
|
||||
UINT64_C(15927076453364631751), UINT64_C(7860239898779391109),
|
||||
static void next_addresses(block *address_block, block *input_block) {
|
||||
/*Temporary zero-initialized blocks*/
|
||||
#if defined(__AVX512F__)
|
||||
__m512i zero_block[ARGON2_512BIT_WORDS_IN_BLOCK];
|
||||
__m512i zero2_block[ARGON2_512BIT_WORDS_IN_BLOCK];
|
||||
#elif defined(__AVX2__)
|
||||
__m256i zero_block[ARGON2_HWORDS_IN_BLOCK];
|
||||
__m256i zero2_block[ARGON2_HWORDS_IN_BLOCK];
|
||||
#else
|
||||
__m128i zero_block[ARGON2_OWORDS_IN_BLOCK];
|
||||
__m128i zero2_block[ARGON2_OWORDS_IN_BLOCK];
|
||||
#endif
|
||||
|
||||
UINT64_C(11820267568857244377), UINT64_C(12188179869468676617),
|
||||
UINT64_C(3732913385414474778), UINT64_C(7651458777762572084),
|
||||
memset(zero_block, 0, sizeof(zero_block));
|
||||
memset(zero2_block, 0, sizeof(zero2_block));
|
||||
|
||||
UINT64_C(3062274162574341415), UINT64_C(17922653540258786897),
|
||||
UINT64_C(17393848266100524980), UINT64_C(8539695715554563839),
|
||||
/*Increasing index counter*/
|
||||
input_block->v[6]++;
|
||||
|
||||
UINT64_C(13824538050656654359), UINT64_C(12078939433126460936),
|
||||
UINT64_C(15331979418564540430), UINT64_C(12058346794217174273),
|
||||
/*First iteration of G*/
|
||||
fill_block(zero_block, input_block, address_block, 0);
|
||||
|
||||
UINT64_C(13593922096015221049), UINT64_C(18356682276374416500),
|
||||
UINT64_C(4968040514092703824), UINT64_C(11202790346130235567),
|
||||
|
||||
UINT64_C(2276229735041314644), UINT64_C(220837743321691382),
|
||||
UINT64_C(4861211596230784273), UINT64_C(6330592584132590331),
|
||||
|
||||
UINT64_C(3515580430960296763), UINT64_C(9869356316971855173),
|
||||
UINT64_C(485533243489193056), UINT64_C(14596447761048148032),
|
||||
|
||||
UINT64_C(16531790085730132900), UINT64_C(17328824500878824371),
|
||||
UINT64_C(8548260058287621283), UINT64_C(8641748798041936364)
|
||||
};
|
||||
|
||||
void generate_addresses(const argon2_instance_t *instance,
|
||||
const argon2_position_t *position,
|
||||
uint64_t *pseudo_rands)
|
||||
{
|
||||
uint8_t offset = position->pass * 16 + position->slice * 4;
|
||||
pseudo_rands[0] = bad_rands[offset++];
|
||||
pseudo_rands[1] = bad_rands[offset++];
|
||||
pseudo_rands[2] = bad_rands[offset++];
|
||||
pseudo_rands[3] = bad_rands[offset++];
|
||||
|
||||
/*if ((position->pass == 1 && position->slice == 3))
|
||||
print64("pseudo_rands", pseudo_rands, 4);*/
|
||||
/*Second iteration of G*/
|
||||
fill_block(zero2_block, address_block, address_block, 0);
|
||||
}
|
||||
|
||||
#define SEGMENT_LENGTH 4
|
||||
#define LANE_LENGTH 16
|
||||
#define POS_LANE 0
|
||||
|
||||
void fill_segment(const argon2_instance_t *instance,
|
||||
argon2_position_t position)
|
||||
{
|
||||
argon2_position_t position) {
|
||||
block *ref_block = NULL, *curr_block = NULL;
|
||||
uint64_t pseudo_rand, ref_index;
|
||||
block address_block, input_block;
|
||||
uint64_t pseudo_rand, ref_index, ref_lane;
|
||||
uint32_t prev_offset, curr_offset;
|
||||
uint8_t i;
|
||||
__m128i state[64];
|
||||
int data_independent_addressing = (instance->type == Argon2_i);
|
||||
uint32_t starting_index, i;
|
||||
#if defined(__AVX512F__)
|
||||
__m512i state[ARGON2_512BIT_WORDS_IN_BLOCK];
|
||||
#elif defined(__AVX2__)
|
||||
__m256i state[ARGON2_HWORDS_IN_BLOCK];
|
||||
#else
|
||||
__m128i state[ARGON2_OWORDS_IN_BLOCK];
|
||||
#endif
|
||||
int data_independent_addressing;
|
||||
|
||||
/* Pseudo-random values that determine the reference block position */
|
||||
uint64_t *pseudo_rands = NULL;
|
||||
|
||||
pseudo_rands = (uint64_t *)malloc(/*sizeof(uint64_t) * 4*/32);
|
||||
|
||||
if (data_independent_addressing) {
|
||||
generate_addresses(instance, &position, pseudo_rands);
|
||||
if (instance == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
starting_index = 0;
|
||||
|
||||
if ((0 == position.pass) && (0 == position.slice)) {
|
||||
i = 2; /* we have already generated the first two blocks */
|
||||
starting_index = 2; /* we have already generated the first two blocks */
|
||||
|
||||
/* Don't forget to generate the first block of addresses: */
|
||||
if (data_independent_addressing) {
|
||||
next_addresses(&address_block, &input_block);
|
||||
}
|
||||
}
|
||||
|
||||
/*printf("Position.lane = %d\nPosition.slice = %d\nStarting index : %d\n", position.lane, position.slice, starting_index);*/
|
||||
/* Offset of the current block */
|
||||
curr_offset = position.slice * 4 + i;
|
||||
curr_offset = position.lane * instance->lane_length +
|
||||
position.slice * instance->segment_length + starting_index;
|
||||
|
||||
if (0 == curr_offset % 16) {
|
||||
if (0 == curr_offset % instance->lane_length) {
|
||||
/* Last block in this lane */
|
||||
prev_offset = curr_offset + /*instance->lane_length - 1*/15;
|
||||
prev_offset = curr_offset + instance->lane_length - 1;
|
||||
} else {
|
||||
/* Previous block */
|
||||
prev_offset = curr_offset - 1;
|
||||
|
@ -152,34 +216,45 @@ void fill_segment(const argon2_instance_t *instance,
|
|||
|
||||
memcpy(state, ((instance->memory + prev_offset)->v), ARGON2_BLOCK_SIZE);
|
||||
|
||||
for (; i < SEGMENT_LENGTH;
|
||||
for (i = starting_index; i < instance->segment_length;
|
||||
++i, ++curr_offset, ++prev_offset) {
|
||||
/*1.1 Rotating prev_offset if needed */
|
||||
if (curr_offset % LANE_LENGTH == 1) {
|
||||
if (curr_offset % instance->lane_length == 1) {
|
||||
prev_offset = curr_offset - 1;
|
||||
}
|
||||
|
||||
/* 1.2 Computing the index of the reference block */
|
||||
/* 1.2.1 Taking pseudo-random value from the previous block */
|
||||
if (data_independent_addressing) {
|
||||
pseudo_rand = pseudo_rands[i];
|
||||
if (i % ARGON2_ADDRESSES_IN_BLOCK == 0) {
|
||||
next_addresses(&address_block, &input_block);
|
||||
}
|
||||
pseudo_rand = address_block.v[i % ARGON2_ADDRESSES_IN_BLOCK];
|
||||
} else {
|
||||
pseudo_rand = instance->memory[prev_offset].v[0];
|
||||
}
|
||||
|
||||
/* 1.2.2 Computing the lane of the reference block */
|
||||
ref_lane = ((pseudo_rand >> 32)) % instance->lanes;
|
||||
|
||||
if ((position.pass == 0) && (position.slice == 0)) {
|
||||
/* Can not reference other lanes yet */
|
||||
ref_lane = position.lane;
|
||||
}
|
||||
|
||||
/* 1.2.3 Computing the number of possible reference block within the
|
||||
* lane.
|
||||
*/
|
||||
position.index = i;
|
||||
ref_index = index_alpha(instance, &position, pseudo_rand & 0xFFFFFFFF,1);
|
||||
ref_index = index_alpha(instance, &position, pseudo_rand & 0xFFFFFFFF,
|
||||
ref_lane == position.lane);
|
||||
|
||||
/* 2 Creating a new block */
|
||||
ref_block = instance->memory + ref_index;
|
||||
ref_block =
|
||||
instance->memory + instance->lane_length * ref_lane + ref_index;
|
||||
curr_block = instance->memory + curr_offset;
|
||||
fill_block(state, (__m128i const *)ref_block->v, (__m128i *)curr_block->v);
|
||||
}
|
||||
|
||||
free(pseudo_rands);
|
||||
fill_block(state, ref_block, curr_block, 0);
|
||||
|
||||
}
|
||||
}
|
|
@ -1,49 +0,0 @@
|
|||
/*
|
||||
* Argon2 source code package
|
||||
*
|
||||
* Written by Daniel Dinu and Dmitry Khovratovich, 2015
|
||||
*
|
||||
* This work is licensed under a Creative Commons CC0 1.0 License/Waiver.
|
||||
*
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along
|
||||
* with
|
||||
* this software. If not, see
|
||||
* <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
*/
|
||||
|
||||
#ifndef ARGON2_OPT_H
|
||||
#define ARGON2_OPT_H
|
||||
|
||||
/*
|
||||
* Function fills a new memory block. Differs from the
|
||||
* @param state Pointer to the just produced block. Content will be updated(!)
|
||||
* @param ref_block Pointer to the reference block
|
||||
* @param next_block Pointer to the block to be constructed
|
||||
* @pre all block pointers must be valid
|
||||
*/
|
||||
void fill_block(__m128i *state, __m128i const *ref_block, __m128i *next_block);
|
||||
|
||||
/*
|
||||
* Generate pseudo-random values to reference blocks in the segment and puts
|
||||
* them into the array
|
||||
* @param instance Pointer to the current instance
|
||||
* @param position Pointer to the current position
|
||||
* @param pseudo_rands Pointer to the array of 64-bit values
|
||||
* @pre pseudo_rands must point to @a instance->segment_length allocated values
|
||||
*/
|
||||
void generate_addresses(const argon2_instance_t *instance,
|
||||
const argon2_position_t *position,
|
||||
uint64_t *pseudo_rands);
|
||||
|
||||
/*
|
||||
* Function that fills the segment using previous segments also from other
|
||||
* threads.
|
||||
* Identical to the reference code except that it calls optimized FillBlock()
|
||||
* @param instance Pointer to the current instance
|
||||
* @param position Current position
|
||||
* @pre all block pointers must be valid
|
||||
*/
|
||||
void fill_segment(const argon2_instance_t *instance,
|
||||
argon2_position_t position);
|
||||
|
||||
#endif /* ARGON2_OPT_H */
|
|
@ -1,174 +0,0 @@
|
|||
/*
|
||||
* Argon2 source code package
|
||||
*
|
||||
* Written by Daniel Dinu and Dmitry Khovratovich, 2015
|
||||
*
|
||||
* This work is licensed under a Creative Commons CC0 1.0 License/Waiver.
|
||||
*
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along
|
||||
* with
|
||||
* this software. If not, see
|
||||
* <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "argon2.h"
|
||||
#include "cores.h"
|
||||
#include "ref.h"
|
||||
|
||||
#include "blake2/blamka-round-ref.h"
|
||||
#include "blake2/blake2-impl.h"
|
||||
#include "blake2/blake2.h"
|
||||
|
||||
void fill_block(const block *prev_block, const block *ref_block,
|
||||
block *next_block) {
|
||||
block blockR, block_tmp;
|
||||
unsigned i;
|
||||
|
||||
copy_block(&blockR, ref_block);
|
||||
xor_block(&blockR, prev_block);
|
||||
copy_block(&block_tmp, &blockR);
|
||||
|
||||
/* Apply Blake2 on columns of 64-bit words: (0,1,...,15) , then
|
||||
(16,17,..31)... finally (112,113,...127) */
|
||||
for (i = 0; i < 8; ++i) {
|
||||
BLAKE2_ROUND_NOMSG(
|
||||
blockR.v[16 * i], blockR.v[16 * i + 1], blockR.v[16 * i + 2],
|
||||
blockR.v[16 * i + 3], blockR.v[16 * i + 4], blockR.v[16 * i + 5],
|
||||
blockR.v[16 * i + 6], blockR.v[16 * i + 7], blockR.v[16 * i + 8],
|
||||
blockR.v[16 * i + 9], blockR.v[16 * i + 10], blockR.v[16 * i + 11],
|
||||
blockR.v[16 * i + 12], blockR.v[16 * i + 13], blockR.v[16 * i + 14],
|
||||
blockR.v[16 * i + 15]);
|
||||
}
|
||||
|
||||
/* Apply Blake2 on rows of 64-bit words: (0,1,16,17,...112,113), then
|
||||
(2,3,18,19,...,114,115).. finally (14,15,30,31,...,126,127) */
|
||||
for (i = 0; i < 8; i++) {
|
||||
BLAKE2_ROUND_NOMSG(
|
||||
blockR.v[2 * i], blockR.v[2 * i + 1], blockR.v[2 * i + 16],
|
||||
blockR.v[2 * i + 17], blockR.v[2 * i + 32], blockR.v[2 * i + 33],
|
||||
blockR.v[2 * i + 48], blockR.v[2 * i + 49], blockR.v[2 * i + 64],
|
||||
blockR.v[2 * i + 65], blockR.v[2 * i + 80], blockR.v[2 * i + 81],
|
||||
blockR.v[2 * i + 96], blockR.v[2 * i + 97], blockR.v[2 * i + 112],
|
||||
blockR.v[2 * i + 113]);
|
||||
}
|
||||
|
||||
copy_block(next_block, &block_tmp);
|
||||
xor_block(next_block, &blockR);
|
||||
}
|
||||
|
||||
void generate_addresses(const argon2_instance_t *instance,
|
||||
const argon2_position_t *position,
|
||||
uint64_t *pseudo_rands) {
|
||||
block zero_block, input_block, address_block;
|
||||
uint32_t i;
|
||||
|
||||
init_block_value(&zero_block, 0);
|
||||
init_block_value(&input_block, 0);
|
||||
init_block_value(&address_block, 0);
|
||||
|
||||
if (instance != NULL && position != NULL) {
|
||||
input_block.v[0] = position->pass;
|
||||
input_block.v[1] = position->lane;
|
||||
input_block.v[2] = position->slice;
|
||||
input_block.v[3] = 16;
|
||||
input_block.v[4] = 2;
|
||||
input_block.v[5] = instance->type;
|
||||
|
||||
for (i = 0; i < 4; ++i) {
|
||||
if (i % ARGON2_ADDRESSES_IN_BLOCK == 0) {
|
||||
input_block.v[6]++;
|
||||
fill_block(&zero_block, &input_block, &address_block);
|
||||
fill_block(&zero_block, &address_block, &address_block);
|
||||
}
|
||||
|
||||
pseudo_rands[i] = address_block.v[i % ARGON2_ADDRESSES_IN_BLOCK];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void fill_segment(const argon2_instance_t *instance,
|
||||
argon2_position_t position) {
|
||||
block *ref_block = NULL, *curr_block = NULL;
|
||||
uint64_t pseudo_rand, ref_index, ref_lane;
|
||||
uint32_t prev_offset, curr_offset;
|
||||
uint32_t starting_index;
|
||||
uint32_t i;
|
||||
int data_independent_addressing = (instance->type == Argon2_i);
|
||||
/* Pseudo-random values that determine the reference block position */
|
||||
uint64_t *pseudo_rands = NULL;
|
||||
|
||||
if (instance == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
pseudo_rands =
|
||||
(uint64_t *)malloc(sizeof(uint64_t) * 4);
|
||||
|
||||
if (pseudo_rands == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (data_independent_addressing) {
|
||||
generate_addresses(instance, &position, pseudo_rands);
|
||||
}
|
||||
|
||||
starting_index = 0;
|
||||
|
||||
if ((0 == position.pass) && (0 == position.slice)) {
|
||||
starting_index = 2; /* we have already generated the first two blocks */
|
||||
}
|
||||
|
||||
/* Offset of the current block */
|
||||
curr_offset = position.lane * 16 +
|
||||
position.slice * 4 + starting_index;
|
||||
|
||||
if (0 == curr_offset % 16) {
|
||||
/* Last block in this lane */
|
||||
prev_offset = curr_offset + 16 - 1;
|
||||
} else {
|
||||
/* Previous block */
|
||||
prev_offset = curr_offset - 1;
|
||||
}
|
||||
|
||||
for (i = starting_index; i < 4; ++i, ++curr_offset, ++prev_offset) {
|
||||
/*1.1 Rotating prev_offset if needed */
|
||||
if (curr_offset % 16 == 1) {
|
||||
prev_offset = curr_offset - 1;
|
||||
}
|
||||
|
||||
/* 1.2 Computing the index of the reference block */
|
||||
/* 1.2.1 Taking pseudo-random value from the previous block */
|
||||
if (data_independent_addressing) {
|
||||
pseudo_rand = pseudo_rands[i];
|
||||
} else {
|
||||
pseudo_rand = instance->memory[prev_offset].v[0];
|
||||
}
|
||||
|
||||
/* 1.2.2 Computing the lane of the reference block */
|
||||
ref_lane = ((pseudo_rand >> 32)) % 1;
|
||||
|
||||
if ((position.pass == 0) && (position.slice == 0)) {
|
||||
/* Can not reference other lanes yet */
|
||||
ref_lane = position.lane;
|
||||
}
|
||||
|
||||
/* 1.2.3 Computing the number of possible reference block within the
|
||||
* lane.
|
||||
*/
|
||||
position.index = i;
|
||||
ref_index = index_alpha(instance, &position, pseudo_rand & 0xFFFFFFFF,
|
||||
ref_lane == position.lane);
|
||||
|
||||
/* 2 Creating a new block */
|
||||
ref_block =
|
||||
instance->memory + 16 * ref_lane + ref_index;
|
||||
curr_block = instance->memory + curr_offset;
|
||||
fill_block(instance->memory + prev_offset, ref_block, curr_block);
|
||||
}
|
||||
|
||||
free(pseudo_rands);
|
||||
}
|
|
@ -1,49 +0,0 @@
|
|||
/*
|
||||
* Argon2 source code package
|
||||
*
|
||||
* Written by Daniel Dinu and Dmitry Khovratovich, 2015
|
||||
*
|
||||
* This work is licensed under a Creative Commons CC0 1.0 License/Waiver.
|
||||
*
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along
|
||||
* with
|
||||
* this software. If not, see
|
||||
* <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
*/
|
||||
|
||||
#ifndef ARGON2_REF_H
|
||||
#define ARGON2_REF_H
|
||||
|
||||
/*
|
||||
* Function fills a new memory block
|
||||
* @param prev_block Pointer to the previous block
|
||||
* @param ref_block Pointer to the reference block
|
||||
* @param next_block Pointer to the block to be constructed
|
||||
* @pre all block pointers must be valid
|
||||
*/
|
||||
void fill_block(const block *prev_block, const block *ref_block,
|
||||
block *next_block);
|
||||
|
||||
/*
|
||||
* Generate pseudo-random values to reference blocks in the segment and puts
|
||||
* them into the array
|
||||
* @param instance Pointer to the current instance
|
||||
* @param position Pointer to the current position
|
||||
* @param pseudo_rands Pointer to the array of 64-bit values
|
||||
* @pre pseudo_rands must point to @a instance->segment_length allocated values
|
||||
*/
|
||||
void generate_addresses(const argon2_instance_t *instance,
|
||||
const argon2_position_t *position,
|
||||
uint64_t *pseudo_rands);
|
||||
|
||||
/*
|
||||
* Function that fills the segment using previous segments also from other
|
||||
* threads
|
||||
* @param instance Pointer to the current instance
|
||||
* @param position Current position
|
||||
* @pre all block pointers must be valid
|
||||
*/
|
||||
void fill_segment(const argon2_instance_t *instance,
|
||||
argon2_position_t position);
|
||||
|
||||
#endif /* ARGON2_REF_H */
|
|
@ -1,223 +0,0 @@
|
|||
/*
|
||||
* Argon2 source code package
|
||||
*
|
||||
* Written by Daniel Dinu and Dmitry Khovratovich, 2015
|
||||
*
|
||||
* This work is licensed under a Creative Commons CC0 1.0 License/Waiver.
|
||||
*
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along
|
||||
* with
|
||||
* this software. If not, see
|
||||
* <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "argon2.h"
|
||||
#include "cores.h"
|
||||
|
||||
#define T_COST_DEF 3
|
||||
#define LOG_M_COST_DEF 12 /* 2^12 = 4 MiB */
|
||||
#define LANES_DEF 1
|
||||
#define THREADS_DEF 1
|
||||
#define OUT_LEN 32
|
||||
#define SALT_LEN 16
|
||||
|
||||
#define UNUSED_PARAMETER(x) (void)(x)
|
||||
|
||||
static void usage(const char *cmd) {
|
||||
printf("Usage: %s pwd salt [-y version] [-t iterations] [-m memory] [-p "
|
||||
"parallelism]\n",
|
||||
cmd);
|
||||
|
||||
printf("Parameters:\n");
|
||||
printf("\tpwd\t\tThe password to hash\n");
|
||||
printf("\tsalt\t\tThe salt to use, at most 16 characters\n");
|
||||
printf("\t-d\t\tUse Argon2d instead of Argon2i (which is the default)\n");
|
||||
printf("\t-t N\t\tSets the number of iterations to N (default = %d)\n",
|
||||
T_COST_DEF);
|
||||
printf("\t-m N\t\tSets the memory usage of 2^N KiB (default %d)\n",
|
||||
LOG_M_COST_DEF);
|
||||
printf("\t-p N\t\tSets parallelism to N threads (default %d)\n",
|
||||
THREADS_DEF);
|
||||
}
|
||||
|
||||
static void fatal(const char *error) {
|
||||
fprintf(stderr, "Error: %s\n", error);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/*
|
||||
Runs Argon2 with certain inputs and parameters, inputs not cleared. Prints the
|
||||
Base64-encoded hash string
|
||||
@out output array with at least 32 bytes allocated
|
||||
@pwd NULL-terminated string, presumably from argv[]
|
||||
@salt salt array with at least SALTLEN_DEF bytes allocated
|
||||
@t_cost number of iterations
|
||||
@m_cost amount of requested memory in KB
|
||||
@lanes amount of requested parallelism
|
||||
@threads actual parallelism
|
||||
@type String, only "d" and "i" are accepted
|
||||
*/
|
||||
static void run(uint8_t *out, char *pwd, uint8_t *salt, uint32_t t_cost,
|
||||
uint32_t m_cost, uint32_t lanes, uint32_t threads,
|
||||
const char *type) {
|
||||
clock_t start_time, stop_time;
|
||||
unsigned pwd_length;
|
||||
argon2_context context;
|
||||
int i;
|
||||
|
||||
start_time = clock();
|
||||
|
||||
if (!pwd) {
|
||||
fatal("password missing");
|
||||
}
|
||||
|
||||
if (!salt) {
|
||||
secure_wipe_memory(pwd, strlen(pwd));
|
||||
fatal("salt missing");
|
||||
}
|
||||
|
||||
pwd_length = strlen(pwd);
|
||||
|
||||
UNUSED_PARAMETER(threads);
|
||||
|
||||
context.out = out;
|
||||
context.outlen = OUT_LEN;
|
||||
context.pwd = (uint8_t *)pwd;
|
||||
context.pwdlen = pwd_length;
|
||||
context.salt = salt;
|
||||
context.saltlen = SALT_LEN;
|
||||
context.secret = NULL;
|
||||
context.secretlen = 0;
|
||||
context.ad = NULL;
|
||||
context.adlen = 0;
|
||||
context.t_cost = t_cost;
|
||||
context.m_cost = m_cost;
|
||||
context.lanes = lanes;
|
||||
context.threads = lanes;
|
||||
context.allocate_cbk = NULL;
|
||||
context.free_cbk = NULL;
|
||||
context.flags = ARGON2_FLAG_CLEAR_PASSWORD;
|
||||
|
||||
if (!strcmp(type, "d")) {
|
||||
int result = argon2d(&context);
|
||||
if (result != ARGON2_OK)
|
||||
fatal(error_message(result));
|
||||
} else if (!strcmp(type, "i")) {
|
||||
int result = argon2i(&context);
|
||||
if (result != ARGON2_OK)
|
||||
fatal(error_message(result));
|
||||
} else {
|
||||
secure_wipe_memory(pwd, strlen(pwd));
|
||||
fatal("wrong Argon2 type");
|
||||
}
|
||||
|
||||
stop_time = clock();
|
||||
|
||||
/* add back when proper decoding */
|
||||
/*
|
||||
char encoded[300];
|
||||
encode_string(encoded, sizeof encoded, &context);
|
||||
printf("%s\n", encoded);
|
||||
*/
|
||||
printf("Hash:\t\t");
|
||||
for (i = 0; i < context.outlen; ++i) {
|
||||
printf("%02x", context.out[i]);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
printf("%2.3f seconds\n",
|
||||
((double)stop_time - start_time) / (CLOCKS_PER_SEC));
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
unsigned char out[OUT_LEN];
|
||||
uint32_t m_cost = 1 << LOG_M_COST_DEF;
|
||||
uint32_t t_cost = T_COST_DEF;
|
||||
uint32_t lanes = LANES_DEF;
|
||||
uint32_t threads = THREADS_DEF;
|
||||
char *pwd = NULL;
|
||||
uint8_t salt[SALT_LEN];
|
||||
const char *type = "i";
|
||||
int i;
|
||||
|
||||
if (argc < 3) {
|
||||
usage(argv[0]);
|
||||
return ARGON2_MISSING_ARGS;
|
||||
}
|
||||
|
||||
/* get password and salt from command line */
|
||||
pwd = argv[1];
|
||||
if (strlen(argv[2]) > SALT_LEN) {
|
||||
fatal("salt too long");
|
||||
}
|
||||
memset(salt, 0x00, SALT_LEN); /* pad with null bytes */
|
||||
memcpy(salt, argv[2], strlen(argv[2]));
|
||||
|
||||
/* parse options */
|
||||
for (i = 3; i < argc; i++) {
|
||||
const char *a = argv[i];
|
||||
unsigned long input = 0;
|
||||
if (!strcmp(a, "-m")) {
|
||||
if (i < argc - 1) {
|
||||
i++;
|
||||
input = strtoul(argv[i], NULL, 10);
|
||||
if (input == 0 || input == ULONG_MAX ||
|
||||
input > ARGON2_MAX_MEMORY_BITS) {
|
||||
fatal("bad numeric input for -m");
|
||||
}
|
||||
m_cost = ARGON2_MIN(UINT64_C(1) << input, UINT32_C(0xFFFFFFFF));
|
||||
if (m_cost > ARGON2_MAX_MEMORY) {
|
||||
fatal("m_cost overflow");
|
||||
}
|
||||
continue;
|
||||
} else {
|
||||
fatal("missing -m argument");
|
||||
}
|
||||
} else if (!strcmp(a, "-t")) {
|
||||
if (i < argc - 1) {
|
||||
i++;
|
||||
input = strtoul(argv[i], NULL, 10);
|
||||
if (input == 0 || input == ULONG_MAX ||
|
||||
input > ARGON2_MAX_TIME) {
|
||||
fatal("bad numeric input for -t");
|
||||
}
|
||||
t_cost = input;
|
||||
continue;
|
||||
} else {
|
||||
fatal("missing -t argument");
|
||||
}
|
||||
} else if (!strcmp(a, "-p")) {
|
||||
if (i < argc - 1) {
|
||||
i++;
|
||||
input = strtoul(argv[i], NULL, 10);
|
||||
if (input == 0 || input == ULONG_MAX ||
|
||||
input > ARGON2_MAX_THREADS || input > ARGON2_MAX_LANES) {
|
||||
fatal("bad numeric input for -p");
|
||||
}
|
||||
threads = input;
|
||||
lanes = threads;
|
||||
continue;
|
||||
} else {
|
||||
fatal("missing -p argument");
|
||||
}
|
||||
} else if (!strcmp(a, "-d")) {
|
||||
type = "d";
|
||||
} else {
|
||||
fatal("unknown argument");
|
||||
}
|
||||
}
|
||||
printf("Type:\t\tArgon2%c\n", type[0]);
|
||||
printf("Iterations:\t%" PRIu32 " \n", t_cost);
|
||||
printf("Memory:\t\t%" PRIu32 " KiB\n", m_cost);
|
||||
printf("Parallelism:\t%" PRIu32 " \n", lanes);
|
||||
run(out, pwd, salt, t_cost, m_cost, lanes, threads, type);
|
||||
|
||||
return ARGON2_OK;
|
||||
}
|
57
stratum/algos/ar2/thread.c
Normal file
57
stratum/algos/ar2/thread.c
Normal file
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Argon2 reference source code package - reference C implementations
|
||||
*
|
||||
* Copyright 2015
|
||||
* Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
|
||||
*
|
||||
* You may use this work under the terms of a Creative Commons CC0 1.0
|
||||
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
|
||||
* these licenses can be found at:
|
||||
*
|
||||
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* You should have received a copy of both of these licenses along with this
|
||||
* software. If not, they may be obtained at the above URLs.
|
||||
*/
|
||||
|
||||
#if !defined(ARGON2_NO_THREADS)
|
||||
|
||||
#include "thread.h"
|
||||
#if defined(_WIN32)
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
int argon2_thread_create(argon2_thread_handle_t *handle,
|
||||
argon2_thread_func_t func, void *args) {
|
||||
if (NULL == handle || func == NULL) {
|
||||
return -1;
|
||||
}
|
||||
#if defined(_WIN32)
|
||||
*handle = _beginthreadex(NULL, 0, func, args, 0, NULL);
|
||||
return *handle != 0 ? 0 : -1;
|
||||
#else
|
||||
return pthread_create(handle, NULL, func, args);
|
||||
#endif
|
||||
}
|
||||
|
||||
int argon2_thread_join(argon2_thread_handle_t handle) {
|
||||
#if defined(_WIN32)
|
||||
if (WaitForSingleObject((HANDLE)handle, INFINITE) == WAIT_OBJECT_0) {
|
||||
return CloseHandle((HANDLE)handle) != 0 ? 0 : -1;
|
||||
}
|
||||
return -1;
|
||||
#else
|
||||
return pthread_join(handle, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
void argon2_thread_exit(void) {
|
||||
#if defined(_WIN32)
|
||||
_endthreadex(0);
|
||||
#else
|
||||
pthread_exit(NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* ARGON2_NO_THREADS */
|
67
stratum/algos/ar2/thread.h
Normal file
67
stratum/algos/ar2/thread.h
Normal file
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* Argon2 reference source code package - reference C implementations
|
||||
*
|
||||
* Copyright 2015
|
||||
* Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
|
||||
*
|
||||
* You may use this work under the terms of a Creative Commons CC0 1.0
|
||||
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
|
||||
* these licenses can be found at:
|
||||
*
|
||||
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* You should have received a copy of both of these licenses along with this
|
||||
* software. If not, they may be obtained at the above URLs.
|
||||
*/
|
||||
|
||||
#ifndef ARGON2_THREAD_H
|
||||
#define ARGON2_THREAD_H
|
||||
|
||||
#if !defined(ARGON2_NO_THREADS)
|
||||
|
||||
/*
|
||||
Here we implement an abstraction layer for the simpĺe requirements
|
||||
of the Argon2 code. We only require 3 primitives---thread creation,
|
||||
joining, and termination---so full emulation of the pthreads API
|
||||
is unwarranted. Currently we wrap pthreads and Win32 threads.
|
||||
|
||||
The API defines 2 types: the function pointer type,
|
||||
argon2_thread_func_t,
|
||||
and the type of the thread handle---argon2_thread_handle_t.
|
||||
*/
|
||||
#if defined(_WIN32)
|
||||
#include <process.h>
|
||||
typedef unsigned(__stdcall *argon2_thread_func_t)(void *);
|
||||
typedef uintptr_t argon2_thread_handle_t;
|
||||
#else
|
||||
#include <pthread.h>
|
||||
typedef void *(*argon2_thread_func_t)(void *);
|
||||
typedef pthread_t argon2_thread_handle_t;
|
||||
#endif
|
||||
|
||||
/* Creates a thread
|
||||
* @param handle pointer to a thread handle, which is the output of this
|
||||
* function. Must not be NULL.
|
||||
* @param func A function pointer for the thread's entry point. Must not be
|
||||
* NULL.
|
||||
* @param args Pointer that is passed as an argument to @func. May be NULL.
|
||||
* @return 0 if @handle and @func are valid pointers and a thread is successfuly
|
||||
* created.
|
||||
*/
|
||||
int argon2_thread_create(argon2_thread_handle_t *handle,
|
||||
argon2_thread_func_t func, void *args);
|
||||
|
||||
/* Waits for a thread to terminate
|
||||
* @param handle Handle to a thread created with argon2_thread_create.
|
||||
* @return 0 if @handle is a valid handle, and joining completed successfully.
|
||||
*/
|
||||
int argon2_thread_join(argon2_thread_handle_t handle);
|
||||
|
||||
/* Terminate the current thread. Must be run inside a thread created by
|
||||
* argon2_thread_create.
|
||||
*/
|
||||
void argon2_thread_exit(void);
|
||||
|
||||
#endif /* ARGON2_NO_THREADS */
|
||||
#endif
|
|
@ -5,8 +5,9 @@
|
|||
|
||||
#include "sysendian.h"
|
||||
|
||||
#include "argon2a.h"
|
||||
#include "ar2/argon2.h"
|
||||
#include "ar2/cores.h"
|
||||
#include "ar2/core.h"
|
||||
#include "ar2/ar2-scrypt-jane.h"
|
||||
|
||||
#define _ALIGN(x) __attribute__ ((aligned(x)))
|
||||
|
@ -24,10 +25,10 @@ inline void argon_call(void *out, void *in, void *salt, int type)
|
|||
context.pwd = (uint8_t *)in;
|
||||
context.salt = (uint8_t *)salt;
|
||||
|
||||
argon2_core(&context, type);
|
||||
argon2_ctx(&context, type);
|
||||
}
|
||||
|
||||
void argon2_hash(const char* input, char* output, uint32_t len)
|
||||
void argon2a_hash(const char* input, char* output, uint32_t len)
|
||||
{
|
||||
uint32_t _ALIGN(32) hashA[8], hashB[8];
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ extern "C" {
|
|||
|
||||
#include <stdint.h>
|
||||
|
||||
void argon2_hash(const char* input, char* output, uint32_t len);
|
||||
void argon2a_hash(const char* input, char* output, uint32_t len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
43
stratum/algos/argon2d-dyn.c
Normal file
43
stratum/algos/argon2d-dyn.c
Normal file
|
@ -0,0 +1,43 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "sysendian.h"
|
||||
|
||||
#include "ar2/argon2.h"
|
||||
#include "ar2/core.h"
|
||||
|
||||
static const size_t INPUT_BYTES = 80; // Lenth of a block header in bytes. Input Length = Salt Length (salt = input)
|
||||
static const size_t OUTPUT_BYTES = 32; // Length of output needed for a 256-bit hash
|
||||
static const unsigned int DEFAULT_ARGON2_FLAG = 2; //Same as ARGON2_DEFAULT_FLAGS
|
||||
|
||||
void argon2d_call(const void *input, void *output)
|
||||
{
|
||||
argon2_context context;
|
||||
context.out = (uint8_t *)output;
|
||||
context.outlen = (uint32_t)OUTPUT_BYTES;
|
||||
context.pwd = (uint8_t *)input;
|
||||
context.pwdlen = (uint32_t)INPUT_BYTES;
|
||||
context.salt = (uint8_t *)input; //salt = input
|
||||
context.saltlen = (uint32_t)INPUT_BYTES;
|
||||
context.secret = NULL;
|
||||
context.secretlen = 0;
|
||||
context.ad = NULL;
|
||||
context.adlen = 0;
|
||||
context.allocate_cbk = NULL;
|
||||
context.free_cbk = NULL;
|
||||
context.flags = DEFAULT_ARGON2_FLAG; // = ARGON2_DEFAULT_FLAGS
|
||||
// main configurable Argon2 hash parameters
|
||||
context.m_cost = 500; // Memory in KiB (512KB)
|
||||
context.lanes = 8; // Degree of Parallelism
|
||||
context.threads = 1; // Threads
|
||||
context.t_cost = 2; // Iterations
|
||||
|
||||
argon2_ctx(&context, Argon2_d);
|
||||
}
|
||||
|
||||
void argon2d_dyn_hash(const unsigned char* input, unsigned char* output, unsigned int len)
|
||||
{
|
||||
argon2d_call(input, output);
|
||||
}
|
16
stratum/algos/argon2d-dyn.h
Normal file
16
stratum/algos/argon2d-dyn.h
Normal file
|
@ -0,0 +1,16 @@
|
|||
#ifndef ARGON2D_H
|
||||
#define ARGON2D_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
void argon2d_dyn_hash(const char* input, char* output, unsigned int len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
102
stratum/algos/bastion.c
Normal file
102
stratum/algos/bastion.c
Normal file
|
@ -0,0 +1,102 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <sha3/sph_hefty1.h>
|
||||
#include <sha3/sph_echo.h>
|
||||
#include <sha3/sph_fugue.h>
|
||||
#include <sha3/sph_whirlpool.h>
|
||||
#include <sha3/sph_skein.h>
|
||||
#include <sha3/sph_echo.h>
|
||||
#include <sha3/sph_luffa.h>
|
||||
#include <sha3/sph_hamsi.h>
|
||||
#include <sha3/sph_shabal.h>
|
||||
|
||||
#define _ALIGN(x) __attribute__ ((aligned(x)))
|
||||
|
||||
void bastion_hash(const char* input, char* output, uint32_t len)
|
||||
{
|
||||
unsigned char _ALIGN(128) hash[64] = { 0 };
|
||||
|
||||
sph_echo512_context ctx_echo;
|
||||
sph_luffa512_context ctx_luffa;
|
||||
sph_fugue512_context ctx_fugue;
|
||||
sph_whirlpool_context ctx_whirlpool;
|
||||
sph_shabal512_context ctx_shabal;
|
||||
sph_skein512_context ctx_skein;
|
||||
sph_hamsi512_context ctx_hamsi;
|
||||
|
||||
HEFTY1(input, len, hash);
|
||||
|
||||
sph_luffa512_init(&ctx_luffa);
|
||||
sph_luffa512(&ctx_luffa, hash, 64);
|
||||
sph_luffa512_close(&ctx_luffa, hash);
|
||||
|
||||
if (hash[0] & 0x8)
|
||||
{
|
||||
sph_fugue512_init(&ctx_fugue);
|
||||
sph_fugue512(&ctx_fugue, hash, 64);
|
||||
sph_fugue512_close(&ctx_fugue, hash);
|
||||
} else {
|
||||
sph_skein512_init(&ctx_skein);
|
||||
sph_skein512(&ctx_skein, hash, 64);
|
||||
sph_skein512_close(&ctx_skein, hash);
|
||||
}
|
||||
|
||||
sph_whirlpool_init(&ctx_whirlpool);
|
||||
sph_whirlpool(&ctx_whirlpool, hash, 64);
|
||||
sph_whirlpool_close(&ctx_whirlpool, hash);
|
||||
|
||||
sph_fugue512_init(&ctx_fugue);
|
||||
sph_fugue512(&ctx_fugue, hash, 64);
|
||||
sph_fugue512_close(&ctx_fugue, hash);
|
||||
|
||||
if (hash[0] & 0x8)
|
||||
{
|
||||
sph_echo512_init(&ctx_echo);
|
||||
sph_echo512(&ctx_echo, hash, 64);
|
||||
sph_echo512_close(&ctx_echo, hash);
|
||||
} else {
|
||||
sph_luffa512_init(&ctx_luffa);
|
||||
sph_luffa512(&ctx_luffa, hash, 64);
|
||||
sph_luffa512_close(&ctx_luffa, hash);
|
||||
}
|
||||
|
||||
sph_shabal512_init(&ctx_shabal);
|
||||
sph_shabal512(&ctx_shabal, hash, 64);
|
||||
sph_shabal512_close(&ctx_shabal, hash);
|
||||
|
||||
sph_skein512_init(&ctx_skein);
|
||||
sph_skein512(&ctx_skein, hash, 64);
|
||||
sph_skein512_close(&ctx_skein, hash);
|
||||
|
||||
if (hash[0] & 0x8)
|
||||
{
|
||||
sph_shabal512_init(&ctx_shabal);
|
||||
sph_shabal512(&ctx_shabal, hash, 64);
|
||||
sph_shabal512_close(&ctx_shabal, hash);
|
||||
} else {
|
||||
sph_whirlpool_init(&ctx_whirlpool);
|
||||
sph_whirlpool(&ctx_whirlpool, hash, 64);
|
||||
sph_whirlpool_close(&ctx_whirlpool, hash);
|
||||
}
|
||||
|
||||
sph_shabal512_init(&ctx_shabal);
|
||||
sph_shabal512(&ctx_shabal, hash, 64);
|
||||
sph_shabal512_close(&ctx_shabal, hash);
|
||||
|
||||
if (hash[0] & 0x8)
|
||||
{
|
||||
sph_hamsi512_init(&ctx_hamsi);
|
||||
sph_hamsi512(&ctx_hamsi, hash, 64);
|
||||
sph_hamsi512_close(&ctx_hamsi, hash);
|
||||
} else {
|
||||
sph_luffa512_init(&ctx_luffa);
|
||||
sph_luffa512(&ctx_luffa, hash, 64);
|
||||
sph_luffa512_close(&ctx_luffa, hash);
|
||||
}
|
||||
|
||||
memcpy(output, hash, 32);
|
||||
}
|
||||
|
16
stratum/algos/bastion.h
Normal file
16
stratum/algos/bastion.h
Normal file
|
@ -0,0 +1,16 @@
|
|||
#ifndef BASTION_H
|
||||
#define BASTION_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
void bastion_hash(const char* input, char* output, uint32_t len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
171
stratum/algos/bitcore.c
Normal file
171
stratum/algos/bitcore.c
Normal file
|
@ -0,0 +1,171 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define HASH_FUNC_BASE_TIMESTAMP 1492973331U // BitCore: Genesis Timestamp
|
||||
#define HASH_FUNC_COUNT 10
|
||||
#define HASH_FUNC_COUNT_PERMUTATIONS 40320
|
||||
|
||||
#include <sha3/sph_blake.h>
|
||||
#include <sha3/sph_bmw.h>
|
||||
#include <sha3/sph_groestl.h>
|
||||
#include <sha3/sph_jh.h>
|
||||
#include <sha3/sph_keccak.h>
|
||||
#include <sha3/sph_skein.h>
|
||||
#include <sha3/sph_luffa.h>
|
||||
#include <sha3/sph_cubehash.h>
|
||||
#include <sha3/sph_shavite.h>
|
||||
#include <sha3/sph_simd.h>
|
||||
|
||||
|
||||
#define _ALIGN(x) __attribute__ ((aligned(x)))
|
||||
|
||||
// helpers
|
||||
inline void swap(int *a, int *b) {
|
||||
int c = *a;
|
||||
*a = *b;
|
||||
*b = c;
|
||||
}
|
||||
|
||||
static void reverse(int *pbegin, int *pend) {
|
||||
while ( (pbegin != pend) && (pbegin != --pend) )
|
||||
swap(pbegin++, pend);
|
||||
}
|
||||
|
||||
static void next_permutation(int *pbegin, int *pend) {
|
||||
if (pbegin == pend)
|
||||
return;
|
||||
|
||||
int *i = pbegin;
|
||||
++i;
|
||||
if (i == pend)
|
||||
return;
|
||||
|
||||
i = pend;
|
||||
--i;
|
||||
|
||||
while (1) {
|
||||
int *j = i;
|
||||
--i;
|
||||
|
||||
if (*i < *j) {
|
||||
int *k = pend;
|
||||
|
||||
while (!(*i < *--k))
|
||||
/* pass */;
|
||||
|
||||
swap(i, k);
|
||||
reverse(j, pend);
|
||||
return; // true
|
||||
}
|
||||
|
||||
if (i == pbegin) {
|
||||
reverse(pbegin, pend);
|
||||
return; // false
|
||||
}
|
||||
}
|
||||
}
|
||||
// helpers
|
||||
|
||||
void timetravel10_hash(const char* input, char* output, uint32_t len)
|
||||
{
|
||||
uint32_t _ALIGN(64) hash[16 * HASH_FUNC_COUNT];
|
||||
uint32_t *hashA, *hashB;
|
||||
uint32_t dataLen = 64;
|
||||
uint32_t *work_data = (uint32_t *)input;
|
||||
const uint32_t timestamp = work_data[17];
|
||||
|
||||
sph_blake512_context ctx_blake;
|
||||
sph_bmw512_context ctx_bmw;
|
||||
sph_groestl512_context ctx_groestl;
|
||||
sph_skein512_context ctx_skein;
|
||||
sph_jh512_context ctx_jh;
|
||||
sph_keccak512_context ctx_keccak;
|
||||
sph_luffa512_context ctx_luffa;
|
||||
sph_cubehash512_context ctx_cubehash;
|
||||
sph_shavite512_context ctx_shavite;
|
||||
sph_simd512_context ctx_simd;
|
||||
|
||||
// We want to permute algorithms. To get started we
|
||||
// initialize an array with a sorted sequence of unique
|
||||
// integers where every integer represents its own algorithm.
|
||||
uint32_t permutation[HASH_FUNC_COUNT];
|
||||
for (uint32_t i = 0; i < HASH_FUNC_COUNT; i++) {
|
||||
permutation[i]=i;
|
||||
}
|
||||
|
||||
// Compute the next permuation
|
||||
uint32_t steps = (timestamp - HASH_FUNC_BASE_TIMESTAMP) % HASH_FUNC_COUNT_PERMUTATIONS;
|
||||
for (uint32_t i = 0; i < steps; i++) {
|
||||
next_permutation(permutation, permutation + HASH_FUNC_COUNT);
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < HASH_FUNC_COUNT; i++) {
|
||||
if (i == 0) {
|
||||
dataLen = len;
|
||||
hashA = work_data;
|
||||
} else {
|
||||
dataLen = 64;
|
||||
hashA = &hash[16 * (i - 1)];
|
||||
}
|
||||
hashB = &hash[16 * i];
|
||||
|
||||
switch(permutation[i]) {
|
||||
case 0:
|
||||
sph_blake512_init(&ctx_blake);
|
||||
sph_blake512(&ctx_blake, hashA, dataLen);
|
||||
sph_blake512_close(&ctx_blake, hashB);
|
||||
break;
|
||||
case 1:
|
||||
sph_bmw512_init(&ctx_bmw);
|
||||
sph_bmw512(&ctx_bmw, hashA, dataLen);
|
||||
sph_bmw512_close(&ctx_bmw, hashB);
|
||||
break;
|
||||
case 2:
|
||||
sph_groestl512_init(&ctx_groestl);
|
||||
sph_groestl512(&ctx_groestl, hashA, dataLen);
|
||||
sph_groestl512_close(&ctx_groestl, hashB);
|
||||
break;
|
||||
case 3:
|
||||
sph_skein512_init(&ctx_skein);
|
||||
sph_skein512(&ctx_skein, hashA, dataLen);
|
||||
sph_skein512_close(&ctx_skein, hashB);
|
||||
break;
|
||||
case 4:
|
||||
sph_jh512_init(&ctx_jh);
|
||||
sph_jh512(&ctx_jh, hashA, dataLen);
|
||||
sph_jh512_close(&ctx_jh, hashB);
|
||||
break;
|
||||
case 5:
|
||||
sph_keccak512_init(&ctx_keccak);
|
||||
sph_keccak512(&ctx_keccak, hashA, dataLen);
|
||||
sph_keccak512_close(&ctx_keccak, hashB);
|
||||
break;
|
||||
case 6:
|
||||
sph_luffa512_init(&ctx_luffa);
|
||||
sph_luffa512(&ctx_luffa, hashA, dataLen);
|
||||
sph_luffa512_close(&ctx_luffa, hashB);
|
||||
break;
|
||||
case 7:
|
||||
sph_cubehash512_init(&ctx_cubehash);
|
||||
sph_cubehash512(&ctx_cubehash, hashA, dataLen);
|
||||
sph_cubehash512_close(&ctx_cubehash, hashB);
|
||||
break;
|
||||
case 8:
|
||||
sph_shavite512_init(&ctx_shavite);
|
||||
sph_shavite512(&ctx_shavite, hashA, dataLen);
|
||||
sph_shavite512_close(&ctx_shavite, hashB);
|
||||
break;
|
||||
case 9:
|
||||
sph_simd512_init(&ctx_simd);
|
||||
sph_simd512(&ctx_simd, hashA, dataLen);
|
||||
sph_simd512_close(&ctx_simd, hashB);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(output, &hash[16 * (HASH_FUNC_COUNT - 1)], 32);
|
||||
}
|
||||
|
16
stratum/algos/bitcore.h
Normal file
16
stratum/algos/bitcore.h
Normal file
|
@ -0,0 +1,16 @@
|
|||
#ifndef TIMETRAVEL10_H
|
||||
#define TIMETRAVEL10_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
void timetravel10_hash(const char* input, char* output, uint32_t len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,3 +1,20 @@
|
|||
/*
|
||||
* Argon2 reference source code package - reference C implementations
|
||||
*
|
||||
* Copyright 2015
|
||||
* Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
|
||||
*
|
||||
* You may use this work under the terms of a Creative Commons CC0 1.0
|
||||
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
|
||||
* these licenses can be found at:
|
||||
*
|
||||
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* You should have received a copy of both of these licenses along with this
|
||||
* software. If not, they may be obtained at the above URLs.
|
||||
*/
|
||||
|
||||
#ifndef PORTABLE_BLAKE2_IMPL_H
|
||||
#define PORTABLE_BLAKE2_IMPL_H
|
||||
|
||||
|
@ -134,10 +151,6 @@ static BLAKE2_INLINE uint64_t rotr64(const uint64_t w, const unsigned c) {
|
|||
return (w >> c) | (w << (64 - c));
|
||||
}
|
||||
|
||||
/* prevents compiler optimizing out memset() */
|
||||
static BLAKE2_INLINE void burn(void *v, size_t n) {
|
||||
static void *(*const volatile memset_v)(void *, int, size_t) = &memset;
|
||||
memset_v(v, 0, n);
|
||||
}
|
||||
void clear_internal_memory(void *v, size_t n);
|
||||
|
||||
#endif
|
|
@ -1,3 +1,20 @@
|
|||
/*
|
||||
* Argon2 reference source code package - reference C implementations
|
||||
*
|
||||
* Copyright 2015
|
||||
* Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
|
||||
*
|
||||
* You may use this work under the terms of a Creative Commons CC0 1.0
|
||||
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
|
||||
* these licenses can be found at:
|
||||
*
|
||||
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* You should have received a copy of both of these licenses along with this
|
||||
* software. If not, they may be obtained at the above URLs.
|
||||
*/
|
||||
|
||||
#ifndef PORTABLE_BLAKE2_H
|
||||
#define PORTABLE_BLAKE2_H
|
||||
|
||||
|
@ -37,10 +54,10 @@ typedef struct __blake2b_state {
|
|||
uint64_t h[8];
|
||||
uint64_t t[2];
|
||||
uint64_t f[2];
|
||||
uint8_t buf[BLAKE2B_BLOCKBYTES];
|
||||
unsigned buflen;
|
||||
unsigned outlen;
|
||||
uint8_t last_node;
|
||||
uint8_t buf[BLAKE2B_BLOCKBYTES];
|
||||
} blake2b_state;
|
||||
|
||||
/* Ensure param structs have not been wrongly padded */
|
||||
|
@ -57,17 +74,15 @@ int blake2b_init_key(blake2b_state *S, size_t outlen, const void *key,
|
|||
size_t keylen);
|
||||
int blake2b_init_param(blake2b_state *S, const blake2b_param *P);
|
||||
int blake2b_update(blake2b_state *S, const void *in, size_t inlen);
|
||||
void my_blake2b_update(blake2b_state *S, const void *in, size_t inlen);
|
||||
int blake2b_final(blake2b_state *S, void *out, size_t outlen);
|
||||
|
||||
/* Simple API */
|
||||
int blake2b(void *out, const void *in, const void *key, size_t keylen);
|
||||
int blake2b(void *out, size_t outlen, const void *in, size_t inlen,
|
||||
const void *key, size_t keylen);
|
||||
|
||||
/* Argon2 Team - Begin Code */
|
||||
int blake2b_long(void *out, const void *in);
|
||||
int blake2b_long(void *out, size_t outlen, const void *in, size_t inlen);
|
||||
/* Argon2 Team - End Code */
|
||||
/* Miouyouyou */
|
||||
void blake2b_too(void *out, const void *in);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
390
stratum/algos/blake2/blake2b.c
Normal file
390
stratum/algos/blake2/blake2b.c
Normal file
|
@ -0,0 +1,390 @@
|
|||
/*
|
||||
* Argon2 reference source code package - reference C implementations
|
||||
*
|
||||
* Copyright 2015
|
||||
* Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
|
||||
*
|
||||
* You may use this work under the terms of a Creative Commons CC0 1.0
|
||||
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
|
||||
* these licenses can be found at:
|
||||
*
|
||||
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* You should have received a copy of both of these licenses along with this
|
||||
* software. If not, they may be obtained at the above URLs.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "blake2.h"
|
||||
#include "blake2-impl.h"
|
||||
|
||||
static const uint64_t blake2b_IV[8] = {
|
||||
UINT64_C(0x6a09e667f3bcc908), UINT64_C(0xbb67ae8584caa73b),
|
||||
UINT64_C(0x3c6ef372fe94f82b), UINT64_C(0xa54ff53a5f1d36f1),
|
||||
UINT64_C(0x510e527fade682d1), UINT64_C(0x9b05688c2b3e6c1f),
|
||||
UINT64_C(0x1f83d9abfb41bd6b), UINT64_C(0x5be0cd19137e2179)};
|
||||
|
||||
static const unsigned int blake2b_sigma[12][16] = {
|
||||
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
|
||||
{14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3},
|
||||
{11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4},
|
||||
{7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8},
|
||||
{9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13},
|
||||
{2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9},
|
||||
{12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11},
|
||||
{13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10},
|
||||
{6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5},
|
||||
{10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0},
|
||||
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
|
||||
{14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3},
|
||||
};
|
||||
|
||||
static BLAKE2_INLINE void blake2b_set_lastnode(blake2b_state *S) {
|
||||
S->f[1] = (uint64_t)-1;
|
||||
}
|
||||
|
||||
static BLAKE2_INLINE void blake2b_set_lastblock(blake2b_state *S) {
|
||||
if (S->last_node) {
|
||||
blake2b_set_lastnode(S);
|
||||
}
|
||||
S->f[0] = (uint64_t)-1;
|
||||
}
|
||||
|
||||
static BLAKE2_INLINE void blake2b_increment_counter(blake2b_state *S,
|
||||
uint64_t inc) {
|
||||
S->t[0] += inc;
|
||||
S->t[1] += (S->t[0] < inc);
|
||||
}
|
||||
|
||||
static BLAKE2_INLINE void blake2b_invalidate_state(blake2b_state *S) {
|
||||
clear_internal_memory(S, sizeof(*S)); /* wipe */
|
||||
blake2b_set_lastblock(S); /* invalidate for further use */
|
||||
}
|
||||
|
||||
static BLAKE2_INLINE void blake2b_init0(blake2b_state *S) {
|
||||
memset(S, 0, sizeof(*S));
|
||||
memcpy(S->h, blake2b_IV, sizeof(S->h));
|
||||
}
|
||||
|
||||
int blake2b_init_param(blake2b_state *S, const blake2b_param *P) {
|
||||
const unsigned char *p = (const unsigned char *)P;
|
||||
unsigned int i;
|
||||
|
||||
if (NULL == P || NULL == S) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
blake2b_init0(S);
|
||||
/* IV XOR Parameter Block */
|
||||
for (i = 0; i < 8; ++i) {
|
||||
S->h[i] ^= load64(&p[i * sizeof(S->h[i])]);
|
||||
}
|
||||
S->outlen = P->digest_length;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Sequential blake2b initialization */
|
||||
int blake2b_init(blake2b_state *S, size_t outlen) {
|
||||
blake2b_param P;
|
||||
|
||||
if (S == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((outlen == 0) || (outlen > BLAKE2B_OUTBYTES)) {
|
||||
blake2b_invalidate_state(S);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Setup Parameter Block for unkeyed BLAKE2 */
|
||||
P.digest_length = (uint8_t)outlen;
|
||||
P.key_length = 0;
|
||||
P.fanout = 1;
|
||||
P.depth = 1;
|
||||
P.leaf_length = 0;
|
||||
P.node_offset = 0;
|
||||
P.node_depth = 0;
|
||||
P.inner_length = 0;
|
||||
memset(P.reserved, 0, sizeof(P.reserved));
|
||||
memset(P.salt, 0, sizeof(P.salt));
|
||||
memset(P.personal, 0, sizeof(P.personal));
|
||||
|
||||
return blake2b_init_param(S, &P);
|
||||
}
|
||||
|
||||
int blake2b_init_key(blake2b_state *S, size_t outlen, const void *key,
|
||||
size_t keylen) {
|
||||
blake2b_param P;
|
||||
|
||||
if (S == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((outlen == 0) || (outlen > BLAKE2B_OUTBYTES)) {
|
||||
blake2b_invalidate_state(S);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((key == 0) || (keylen == 0) || (keylen > BLAKE2B_KEYBYTES)) {
|
||||
blake2b_invalidate_state(S);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Setup Parameter Block for keyed BLAKE2 */
|
||||
P.digest_length = (uint8_t)outlen;
|
||||
P.key_length = (uint8_t)keylen;
|
||||
P.fanout = 1;
|
||||
P.depth = 1;
|
||||
P.leaf_length = 0;
|
||||
P.node_offset = 0;
|
||||
P.node_depth = 0;
|
||||
P.inner_length = 0;
|
||||
memset(P.reserved, 0, sizeof(P.reserved));
|
||||
memset(P.salt, 0, sizeof(P.salt));
|
||||
memset(P.personal, 0, sizeof(P.personal));
|
||||
|
||||
if (blake2b_init_param(S, &P) < 0) {
|
||||
blake2b_invalidate_state(S);
|
||||
return -1;
|
||||
}
|
||||
|
||||
{
|
||||
uint8_t block[BLAKE2B_BLOCKBYTES];
|
||||
memset(block, 0, BLAKE2B_BLOCKBYTES);
|
||||
memcpy(block, key, keylen);
|
||||
blake2b_update(S, block, BLAKE2B_BLOCKBYTES);
|
||||
/* Burn the key from stack */
|
||||
clear_internal_memory(block, BLAKE2B_BLOCKBYTES);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void blake2b_compress(blake2b_state *S, const uint8_t *block) {
|
||||
uint64_t m[16];
|
||||
uint64_t v[16];
|
||||
unsigned int i, r;
|
||||
|
||||
for (i = 0; i < 16; ++i) {
|
||||
m[i] = load64(block + i * sizeof(m[i]));
|
||||
}
|
||||
|
||||
for (i = 0; i < 8; ++i) {
|
||||
v[i] = S->h[i];
|
||||
}
|
||||
|
||||
v[8] = blake2b_IV[0];
|
||||
v[9] = blake2b_IV[1];
|
||||
v[10] = blake2b_IV[2];
|
||||
v[11] = blake2b_IV[3];
|
||||
v[12] = blake2b_IV[4] ^ S->t[0];
|
||||
v[13] = blake2b_IV[5] ^ S->t[1];
|
||||
v[14] = blake2b_IV[6] ^ S->f[0];
|
||||
v[15] = blake2b_IV[7] ^ S->f[1];
|
||||
|
||||
#define G(r, i, a, b, c, d) \
|
||||
do { \
|
||||
a = a + b + m[blake2b_sigma[r][2 * i + 0]]; \
|
||||
d = rotr64(d ^ a, 32); \
|
||||
c = c + d; \
|
||||
b = rotr64(b ^ c, 24); \
|
||||
a = a + b + m[blake2b_sigma[r][2 * i + 1]]; \
|
||||
d = rotr64(d ^ a, 16); \
|
||||
c = c + d; \
|
||||
b = rotr64(b ^ c, 63); \
|
||||
} while ((void)0, 0)
|
||||
|
||||
#define ROUND(r) \
|
||||
do { \
|
||||
G(r, 0, v[0], v[4], v[8], v[12]); \
|
||||
G(r, 1, v[1], v[5], v[9], v[13]); \
|
||||
G(r, 2, v[2], v[6], v[10], v[14]); \
|
||||
G(r, 3, v[3], v[7], v[11], v[15]); \
|
||||
G(r, 4, v[0], v[5], v[10], v[15]); \
|
||||
G(r, 5, v[1], v[6], v[11], v[12]); \
|
||||
G(r, 6, v[2], v[7], v[8], v[13]); \
|
||||
G(r, 7, v[3], v[4], v[9], v[14]); \
|
||||
} while ((void)0, 0)
|
||||
|
||||
for (r = 0; r < 12; ++r) {
|
||||
ROUND(r);
|
||||
}
|
||||
|
||||
for (i = 0; i < 8; ++i) {
|
||||
S->h[i] = S->h[i] ^ v[i] ^ v[i + 8];
|
||||
}
|
||||
|
||||
#undef G
|
||||
#undef ROUND
|
||||
}
|
||||
|
||||
int blake2b_update(blake2b_state *S, const void *in, size_t inlen) {
|
||||
const uint8_t *pin = (const uint8_t *)in;
|
||||
|
||||
if (inlen == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Sanity check */
|
||||
if (S == NULL || in == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Is this a reused state? */
|
||||
if (S->f[0] != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (S->buflen + inlen > BLAKE2B_BLOCKBYTES) {
|
||||
/* Complete current block */
|
||||
size_t left = S->buflen;
|
||||
size_t fill = BLAKE2B_BLOCKBYTES - left;
|
||||
memcpy(&S->buf[left], pin, fill);
|
||||
blake2b_increment_counter(S, BLAKE2B_BLOCKBYTES);
|
||||
blake2b_compress(S, S->buf);
|
||||
S->buflen = 0;
|
||||
inlen -= fill;
|
||||
pin += fill;
|
||||
/* Avoid buffer copies when possible */
|
||||
while (inlen > BLAKE2B_BLOCKBYTES) {
|
||||
blake2b_increment_counter(S, BLAKE2B_BLOCKBYTES);
|
||||
blake2b_compress(S, pin);
|
||||
inlen -= BLAKE2B_BLOCKBYTES;
|
||||
pin += BLAKE2B_BLOCKBYTES;
|
||||
}
|
||||
}
|
||||
memcpy(&S->buf[S->buflen], pin, inlen);
|
||||
S->buflen += (unsigned int)inlen;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int blake2b_final(blake2b_state *S, void *out, size_t outlen) {
|
||||
uint8_t buffer[BLAKE2B_OUTBYTES] = {0};
|
||||
unsigned int i;
|
||||
|
||||
/* Sanity checks */
|
||||
if (S == NULL || out == NULL || outlen < S->outlen) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Is this a reused state? */
|
||||
if (S->f[0] != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
blake2b_increment_counter(S, S->buflen);
|
||||
blake2b_set_lastblock(S);
|
||||
memset(&S->buf[S->buflen], 0, BLAKE2B_BLOCKBYTES - S->buflen); /* Padding */
|
||||
blake2b_compress(S, S->buf);
|
||||
|
||||
for (i = 0; i < 8; ++i) { /* Output full hash to temp buffer */
|
||||
store64(buffer + sizeof(S->h[i]) * i, S->h[i]);
|
||||
}
|
||||
|
||||
memcpy(out, buffer, S->outlen);
|
||||
clear_internal_memory(buffer, sizeof(buffer));
|
||||
clear_internal_memory(S->buf, sizeof(S->buf));
|
||||
clear_internal_memory(S->h, sizeof(S->h));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int blake2b(void *out, size_t outlen, const void *in, size_t inlen,
|
||||
const void *key, size_t keylen) {
|
||||
blake2b_state S;
|
||||
int ret = -1;
|
||||
|
||||
/* Verify parameters */
|
||||
if (NULL == in && inlen > 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (NULL == out || outlen == 0 || outlen > BLAKE2B_OUTBYTES) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if ((NULL == key && keylen > 0) || keylen > BLAKE2B_KEYBYTES) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (keylen > 0) {
|
||||
if (blake2b_init_key(&S, outlen, key, keylen) < 0) {
|
||||
goto fail;
|
||||
}
|
||||
} else {
|
||||
if (blake2b_init(&S, outlen) < 0) {
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
if (blake2b_update(&S, in, inlen) < 0) {
|
||||
goto fail;
|
||||
}
|
||||
ret = blake2b_final(&S, out, outlen);
|
||||
|
||||
fail:
|
||||
clear_internal_memory(&S, sizeof(S));
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Argon2 Team - Begin Code */
|
||||
int blake2b_long(void *pout, size_t outlen, const void *in, size_t inlen) {
|
||||
uint8_t *out = (uint8_t *)pout;
|
||||
blake2b_state blake_state;
|
||||
uint8_t outlen_bytes[sizeof(uint32_t)] = {0};
|
||||
int ret = -1;
|
||||
|
||||
if (outlen > UINT32_MAX) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Ensure little-endian byte order! */
|
||||
store32(outlen_bytes, (uint32_t)outlen);
|
||||
|
||||
#define TRY(statement) \
|
||||
do { \
|
||||
ret = statement; \
|
||||
if (ret < 0) { \
|
||||
goto fail; \
|
||||
} \
|
||||
} while ((void)0, 0)
|
||||
|
||||
if (outlen <= BLAKE2B_OUTBYTES) {
|
||||
TRY(blake2b_init(&blake_state, outlen));
|
||||
TRY(blake2b_update(&blake_state, outlen_bytes, sizeof(outlen_bytes)));
|
||||
TRY(blake2b_update(&blake_state, in, inlen));
|
||||
TRY(blake2b_final(&blake_state, out, outlen));
|
||||
} else {
|
||||
uint32_t toproduce;
|
||||
uint8_t out_buffer[BLAKE2B_OUTBYTES];
|
||||
uint8_t in_buffer[BLAKE2B_OUTBYTES];
|
||||
TRY(blake2b_init(&blake_state, BLAKE2B_OUTBYTES));
|
||||
TRY(blake2b_update(&blake_state, outlen_bytes, sizeof(outlen_bytes)));
|
||||
TRY(blake2b_update(&blake_state, in, inlen));
|
||||
TRY(blake2b_final(&blake_state, out_buffer, BLAKE2B_OUTBYTES));
|
||||
memcpy(out, out_buffer, BLAKE2B_OUTBYTES / 2);
|
||||
out += BLAKE2B_OUTBYTES / 2;
|
||||
toproduce = (uint32_t)outlen - BLAKE2B_OUTBYTES / 2;
|
||||
|
||||
while (toproduce > BLAKE2B_OUTBYTES) {
|
||||
memcpy(in_buffer, out_buffer, BLAKE2B_OUTBYTES);
|
||||
TRY(blake2b(out_buffer, BLAKE2B_OUTBYTES, in_buffer,
|
||||
BLAKE2B_OUTBYTES, NULL, 0));
|
||||
memcpy(out, out_buffer, BLAKE2B_OUTBYTES / 2);
|
||||
out += BLAKE2B_OUTBYTES / 2;
|
||||
toproduce -= BLAKE2B_OUTBYTES / 2;
|
||||
}
|
||||
|
||||
memcpy(in_buffer, out_buffer, BLAKE2B_OUTBYTES);
|
||||
TRY(blake2b(out_buffer, toproduce, in_buffer, BLAKE2B_OUTBYTES, NULL,
|
||||
0));
|
||||
memcpy(out, out_buffer, toproduce);
|
||||
}
|
||||
fail:
|
||||
clear_internal_memory(&blake_state, sizeof(blake_state));
|
||||
return ret;
|
||||
#undef TRY
|
||||
}
|
||||
/* Argon2 Team - End Code */
|
476
stratum/algos/blake2/blamka-round-opt.h
Normal file
476
stratum/algos/blake2/blamka-round-opt.h
Normal file
|
@ -0,0 +1,476 @@
|
|||
/*
|
||||
* Argon2 reference source code package - reference C implementations
|
||||
*
|
||||
* Copyright 2015
|
||||
* Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
|
||||
*
|
||||
* You may use this work under the terms of a Creative Commons CC0 1.0
|
||||
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
|
||||
* these licenses can be found at:
|
||||
*
|
||||
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* You should have received a copy of both of these licenses along with this
|
||||
* software. If not, they may be obtained at the above URLs.
|
||||
*/
|
||||
|
||||
#ifndef BLAKE_ROUND_MKA_OPT_H
|
||||
#define BLAKE_ROUND_MKA_OPT_H
|
||||
|
||||
#if defined(HAVE_CONFIG_H)
|
||||
#include "config/dynamic-config.h"
|
||||
#endif
|
||||
|
||||
#include "blake2-impl.h"
|
||||
|
||||
#include <emmintrin.h>
|
||||
#if defined(__SSSE3__)
|
||||
#include <tmmintrin.h> /* for _mm_shuffle_epi8 and _mm_alignr_epi8 */
|
||||
#endif
|
||||
|
||||
#if defined(__XOP__) && (defined(__GNUC__) || defined(__clang__))
|
||||
#include <x86intrin.h>
|
||||
#endif
|
||||
|
||||
#if !defined(__AVX512F__)
|
||||
#if !defined(__AVX2__)
|
||||
#if !defined(__XOP__)
|
||||
#if defined(__SSSE3__)
|
||||
#define r16 \
|
||||
(_mm_setr_epi8(2, 3, 4, 5, 6, 7, 0, 1, 10, 11, 12, 13, 14, 15, 8, 9))
|
||||
#define r24 \
|
||||
(_mm_setr_epi8(3, 4, 5, 6, 7, 0, 1, 2, 11, 12, 13, 14, 15, 8, 9, 10))
|
||||
#define _mm_roti_epi64(x, c) \
|
||||
(-(c) == 32) \
|
||||
? _mm_shuffle_epi32((x), _MM_SHUFFLE(2, 3, 0, 1)) \
|
||||
: (-(c) == 24) \
|
||||
? _mm_shuffle_epi8((x), r24) \
|
||||
: (-(c) == 16) \
|
||||
? _mm_shuffle_epi8((x), r16) \
|
||||
: (-(c) == 63) \
|
||||
? _mm_xor_si128(_mm_srli_epi64((x), -(c)), \
|
||||
_mm_add_epi64((x), (x))) \
|
||||
: _mm_xor_si128(_mm_srli_epi64((x), -(c)), \
|
||||
_mm_slli_epi64((x), 64 - (-(c))))
|
||||
#else /* defined(__SSE2__) */
|
||||
#define _mm_roti_epi64(r, c) \
|
||||
_mm_xor_si128(_mm_srli_epi64((r), -(c)), _mm_slli_epi64((r), 64 - (-(c))))
|
||||
#endif
|
||||
#else
|
||||
#endif
|
||||
|
||||
static BLAKE2_INLINE __m128i fBlaMka(__m128i x, __m128i y) {
|
||||
const __m128i z = _mm_mul_epu32(x, y);
|
||||
return _mm_add_epi64(_mm_add_epi64(x, y), _mm_add_epi64(z, z));
|
||||
}
|
||||
|
||||
#define G1(A0, B0, C0, D0, A1, B1, C1, D1) \
|
||||
do { \
|
||||
A0 = fBlaMka(A0, B0); \
|
||||
A1 = fBlaMka(A1, B1); \
|
||||
\
|
||||
D0 = _mm_xor_si128(D0, A0); \
|
||||
D1 = _mm_xor_si128(D1, A1); \
|
||||
\
|
||||
D0 = _mm_roti_epi64(D0, -32); \
|
||||
D1 = _mm_roti_epi64(D1, -32); \
|
||||
\
|
||||
C0 = fBlaMka(C0, D0); \
|
||||
C1 = fBlaMka(C1, D1); \
|
||||
\
|
||||
B0 = _mm_xor_si128(B0, C0); \
|
||||
B1 = _mm_xor_si128(B1, C1); \
|
||||
\
|
||||
B0 = _mm_roti_epi64(B0, -24); \
|
||||
B1 = _mm_roti_epi64(B1, -24); \
|
||||
} while ((void)0, 0)
|
||||
|
||||
#define G2(A0, B0, C0, D0, A1, B1, C1, D1) \
|
||||
do { \
|
||||
A0 = fBlaMka(A0, B0); \
|
||||
A1 = fBlaMka(A1, B1); \
|
||||
\
|
||||
D0 = _mm_xor_si128(D0, A0); \
|
||||
D1 = _mm_xor_si128(D1, A1); \
|
||||
\
|
||||
D0 = _mm_roti_epi64(D0, -16); \
|
||||
D1 = _mm_roti_epi64(D1, -16); \
|
||||
\
|
||||
C0 = fBlaMka(C0, D0); \
|
||||
C1 = fBlaMka(C1, D1); \
|
||||
\
|
||||
B0 = _mm_xor_si128(B0, C0); \
|
||||
B1 = _mm_xor_si128(B1, C1); \
|
||||
\
|
||||
B0 = _mm_roti_epi64(B0, -63); \
|
||||
B1 = _mm_roti_epi64(B1, -63); \
|
||||
} while ((void)0, 0)
|
||||
|
||||
#if defined(__SSSE3__)
|
||||
#define DIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1) \
|
||||
do { \
|
||||
__m128i t0 = _mm_alignr_epi8(B1, B0, 8); \
|
||||
__m128i t1 = _mm_alignr_epi8(B0, B1, 8); \
|
||||
B0 = t0; \
|
||||
B1 = t1; \
|
||||
\
|
||||
t0 = C0; \
|
||||
C0 = C1; \
|
||||
C1 = t0; \
|
||||
\
|
||||
t0 = _mm_alignr_epi8(D1, D0, 8); \
|
||||
t1 = _mm_alignr_epi8(D0, D1, 8); \
|
||||
D0 = t1; \
|
||||
D1 = t0; \
|
||||
} while ((void)0, 0)
|
||||
|
||||
#define UNDIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1) \
|
||||
do { \
|
||||
__m128i t0 = _mm_alignr_epi8(B0, B1, 8); \
|
||||
__m128i t1 = _mm_alignr_epi8(B1, B0, 8); \
|
||||
B0 = t0; \
|
||||
B1 = t1; \
|
||||
\
|
||||
t0 = C0; \
|
||||
C0 = C1; \
|
||||
C1 = t0; \
|
||||
\
|
||||
t0 = _mm_alignr_epi8(D0, D1, 8); \
|
||||
t1 = _mm_alignr_epi8(D1, D0, 8); \
|
||||
D0 = t1; \
|
||||
D1 = t0; \
|
||||
} while ((void)0, 0)
|
||||
#else /* SSE2 */
|
||||
#define DIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1) \
|
||||
do { \
|
||||
__m128i t0 = D0; \
|
||||
__m128i t1 = B0; \
|
||||
D0 = C0; \
|
||||
C0 = C1; \
|
||||
C1 = D0; \
|
||||
D0 = _mm_unpackhi_epi64(D1, _mm_unpacklo_epi64(t0, t0)); \
|
||||
D1 = _mm_unpackhi_epi64(t0, _mm_unpacklo_epi64(D1, D1)); \
|
||||
B0 = _mm_unpackhi_epi64(B0, _mm_unpacklo_epi64(B1, B1)); \
|
||||
B1 = _mm_unpackhi_epi64(B1, _mm_unpacklo_epi64(t1, t1)); \
|
||||
} while ((void)0, 0)
|
||||
|
||||
#define UNDIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1) \
|
||||
do { \
|
||||
__m128i t0, t1; \
|
||||
t0 = C0; \
|
||||
C0 = C1; \
|
||||
C1 = t0; \
|
||||
t0 = B0; \
|
||||
t1 = D0; \
|
||||
B0 = _mm_unpackhi_epi64(B1, _mm_unpacklo_epi64(B0, B0)); \
|
||||
B1 = _mm_unpackhi_epi64(t0, _mm_unpacklo_epi64(B1, B1)); \
|
||||
D0 = _mm_unpackhi_epi64(D0, _mm_unpacklo_epi64(D1, D1)); \
|
||||
D1 = _mm_unpackhi_epi64(D1, _mm_unpacklo_epi64(t1, t1)); \
|
||||
} while ((void)0, 0)
|
||||
#endif
|
||||
|
||||
#define BLAKE2_ROUND(A0, A1, B0, B1, C0, C1, D0, D1) \
|
||||
do { \
|
||||
G1(A0, B0, C0, D0, A1, B1, C1, D1); \
|
||||
G2(A0, B0, C0, D0, A1, B1, C1, D1); \
|
||||
\
|
||||
DIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1); \
|
||||
\
|
||||
G1(A0, B0, C0, D0, A1, B1, C1, D1); \
|
||||
G2(A0, B0, C0, D0, A1, B1, C1, D1); \
|
||||
\
|
||||
UNDIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1); \
|
||||
} while ((void)0, 0)
|
||||
|
||||
#else /* __AVX2__ */
|
||||
|
||||
#include <immintrin.h>
|
||||
|
||||
#define rotr32(x) _mm256_shuffle_epi32(x, _MM_SHUFFLE(2, 3, 0, 1))
|
||||
#define rotr24(x) _mm256_shuffle_epi8(x, _mm256_setr_epi8(3, 4, 5, 6, 7, 0, 1, 2, 11, 12, 13, 14, 15, 8, 9, 10, 3, 4, 5, 6, 7, 0, 1, 2, 11, 12, 13, 14, 15, 8, 9, 10))
|
||||
#define rotr16(x) _mm256_shuffle_epi8(x, _mm256_setr_epi8(2, 3, 4, 5, 6, 7, 0, 1, 10, 11, 12, 13, 14, 15, 8, 9, 2, 3, 4, 5, 6, 7, 0, 1, 10, 11, 12, 13, 14, 15, 8, 9))
|
||||
#define rotr63(x) _mm256_xor_si256(_mm256_srli_epi64((x), 63), _mm256_add_epi64((x), (x)))
|
||||
|
||||
#define G1_AVX2(A0, A1, B0, B1, C0, C1, D0, D1) \
|
||||
do { \
|
||||
__m256i ml = _mm256_mul_epu32(A0, B0); \
|
||||
ml = _mm256_add_epi64(ml, ml); \
|
||||
A0 = _mm256_add_epi64(A0, _mm256_add_epi64(B0, ml)); \
|
||||
D0 = _mm256_xor_si256(D0, A0); \
|
||||
D0 = rotr32(D0); \
|
||||
\
|
||||
ml = _mm256_mul_epu32(C0, D0); \
|
||||
ml = _mm256_add_epi64(ml, ml); \
|
||||
C0 = _mm256_add_epi64(C0, _mm256_add_epi64(D0, ml)); \
|
||||
\
|
||||
B0 = _mm256_xor_si256(B0, C0); \
|
||||
B0 = rotr24(B0); \
|
||||
\
|
||||
ml = _mm256_mul_epu32(A1, B1); \
|
||||
ml = _mm256_add_epi64(ml, ml); \
|
||||
A1 = _mm256_add_epi64(A1, _mm256_add_epi64(B1, ml)); \
|
||||
D1 = _mm256_xor_si256(D1, A1); \
|
||||
D1 = rotr32(D1); \
|
||||
\
|
||||
ml = _mm256_mul_epu32(C1, D1); \
|
||||
ml = _mm256_add_epi64(ml, ml); \
|
||||
C1 = _mm256_add_epi64(C1, _mm256_add_epi64(D1, ml)); \
|
||||
\
|
||||
B1 = _mm256_xor_si256(B1, C1); \
|
||||
B1 = rotr24(B1); \
|
||||
} while((void)0, 0);
|
||||
|
||||
#define G2_AVX2(A0, A1, B0, B1, C0, C1, D0, D1) \
|
||||
do { \
|
||||
__m256i ml = _mm256_mul_epu32(A0, B0); \
|
||||
ml = _mm256_add_epi64(ml, ml); \
|
||||
A0 = _mm256_add_epi64(A0, _mm256_add_epi64(B0, ml)); \
|
||||
D0 = _mm256_xor_si256(D0, A0); \
|
||||
D0 = rotr16(D0); \
|
||||
\
|
||||
ml = _mm256_mul_epu32(C0, D0); \
|
||||
ml = _mm256_add_epi64(ml, ml); \
|
||||
C0 = _mm256_add_epi64(C0, _mm256_add_epi64(D0, ml)); \
|
||||
B0 = _mm256_xor_si256(B0, C0); \
|
||||
B0 = rotr63(B0); \
|
||||
\
|
||||
ml = _mm256_mul_epu32(A1, B1); \
|
||||
ml = _mm256_add_epi64(ml, ml); \
|
||||
A1 = _mm256_add_epi64(A1, _mm256_add_epi64(B1, ml)); \
|
||||
D1 = _mm256_xor_si256(D1, A1); \
|
||||
D1 = rotr16(D1); \
|
||||
\
|
||||
ml = _mm256_mul_epu32(C1, D1); \
|
||||
ml = _mm256_add_epi64(ml, ml); \
|
||||
C1 = _mm256_add_epi64(C1, _mm256_add_epi64(D1, ml)); \
|
||||
B1 = _mm256_xor_si256(B1, C1); \
|
||||
B1 = rotr63(B1); \
|
||||
} while((void)0, 0);
|
||||
|
||||
#define DIAGONALIZE_1(A0, B0, C0, D0, A1, B1, C1, D1) \
|
||||
do { \
|
||||
B0 = _mm256_permute4x64_epi64(B0, _MM_SHUFFLE(0, 3, 2, 1)); \
|
||||
C0 = _mm256_permute4x64_epi64(C0, _MM_SHUFFLE(1, 0, 3, 2)); \
|
||||
D0 = _mm256_permute4x64_epi64(D0, _MM_SHUFFLE(2, 1, 0, 3)); \
|
||||
\
|
||||
B1 = _mm256_permute4x64_epi64(B1, _MM_SHUFFLE(0, 3, 2, 1)); \
|
||||
C1 = _mm256_permute4x64_epi64(C1, _MM_SHUFFLE(1, 0, 3, 2)); \
|
||||
D1 = _mm256_permute4x64_epi64(D1, _MM_SHUFFLE(2, 1, 0, 3)); \
|
||||
} while((void)0, 0);
|
||||
|
||||
#define DIAGONALIZE_2(A0, A1, B0, B1, C0, C1, D0, D1) \
|
||||
do { \
|
||||
__m256i tmp1 = _mm256_blend_epi32(B0, B1, 0xCC); \
|
||||
__m256i tmp2 = _mm256_blend_epi32(B0, B1, 0x33); \
|
||||
B1 = _mm256_permute4x64_epi64(tmp1, _MM_SHUFFLE(2,3,0,1)); \
|
||||
B0 = _mm256_permute4x64_epi64(tmp2, _MM_SHUFFLE(2,3,0,1)); \
|
||||
\
|
||||
tmp1 = C0; \
|
||||
C0 = C1; \
|
||||
C1 = tmp1; \
|
||||
\
|
||||
tmp1 = _mm256_blend_epi32(D0, D1, 0xCC); \
|
||||
tmp2 = _mm256_blend_epi32(D0, D1, 0x33); \
|
||||
D0 = _mm256_permute4x64_epi64(tmp1, _MM_SHUFFLE(2,3,0,1)); \
|
||||
D1 = _mm256_permute4x64_epi64(tmp2, _MM_SHUFFLE(2,3,0,1)); \
|
||||
} while(0);
|
||||
|
||||
#define UNDIAGONALIZE_1(A0, B0, C0, D0, A1, B1, C1, D1) \
|
||||
do { \
|
||||
B0 = _mm256_permute4x64_epi64(B0, _MM_SHUFFLE(2, 1, 0, 3)); \
|
||||
C0 = _mm256_permute4x64_epi64(C0, _MM_SHUFFLE(1, 0, 3, 2)); \
|
||||
D0 = _mm256_permute4x64_epi64(D0, _MM_SHUFFLE(0, 3, 2, 1)); \
|
||||
\
|
||||
B1 = _mm256_permute4x64_epi64(B1, _MM_SHUFFLE(2, 1, 0, 3)); \
|
||||
C1 = _mm256_permute4x64_epi64(C1, _MM_SHUFFLE(1, 0, 3, 2)); \
|
||||
D1 = _mm256_permute4x64_epi64(D1, _MM_SHUFFLE(0, 3, 2, 1)); \
|
||||
} while((void)0, 0);
|
||||
|
||||
#define UNDIAGONALIZE_2(A0, A1, B0, B1, C0, C1, D0, D1) \
|
||||
do { \
|
||||
__m256i tmp1 = _mm256_blend_epi32(B0, B1, 0xCC); \
|
||||
__m256i tmp2 = _mm256_blend_epi32(B0, B1, 0x33); \
|
||||
B0 = _mm256_permute4x64_epi64(tmp1, _MM_SHUFFLE(2,3,0,1)); \
|
||||
B1 = _mm256_permute4x64_epi64(tmp2, _MM_SHUFFLE(2,3,0,1)); \
|
||||
\
|
||||
tmp1 = C0; \
|
||||
C0 = C1; \
|
||||
C1 = tmp1; \
|
||||
\
|
||||
tmp1 = _mm256_blend_epi32(D0, D1, 0x33); \
|
||||
tmp2 = _mm256_blend_epi32(D0, D1, 0xCC); \
|
||||
D0 = _mm256_permute4x64_epi64(tmp1, _MM_SHUFFLE(2,3,0,1)); \
|
||||
D1 = _mm256_permute4x64_epi64(tmp2, _MM_SHUFFLE(2,3,0,1)); \
|
||||
} while((void)0, 0);
|
||||
|
||||
#define BLAKE2_ROUND_1(A0, A1, B0, B1, C0, C1, D0, D1) \
|
||||
do{ \
|
||||
G1_AVX2(A0, A1, B0, B1, C0, C1, D0, D1) \
|
||||
G2_AVX2(A0, A1, B0, B1, C0, C1, D0, D1) \
|
||||
\
|
||||
DIAGONALIZE_1(A0, B0, C0, D0, A1, B1, C1, D1) \
|
||||
\
|
||||
G1_AVX2(A0, A1, B0, B1, C0, C1, D0, D1) \
|
||||
G2_AVX2(A0, A1, B0, B1, C0, C1, D0, D1) \
|
||||
\
|
||||
UNDIAGONALIZE_1(A0, B0, C0, D0, A1, B1, C1, D1) \
|
||||
} while((void)0, 0);
|
||||
|
||||
#define BLAKE2_ROUND_2(A0, A1, B0, B1, C0, C1, D0, D1) \
|
||||
do{ \
|
||||
G1_AVX2(A0, A1, B0, B1, C0, C1, D0, D1) \
|
||||
G2_AVX2(A0, A1, B0, B1, C0, C1, D0, D1) \
|
||||
\
|
||||
DIAGONALIZE_2(A0, A1, B0, B1, C0, C1, D0, D1) \
|
||||
\
|
||||
G1_AVX2(A0, A1, B0, B1, C0, C1, D0, D1) \
|
||||
G2_AVX2(A0, A1, B0, B1, C0, C1, D0, D1) \
|
||||
\
|
||||
UNDIAGONALIZE_2(A0, A1, B0, B1, C0, C1, D0, D1) \
|
||||
} while((void)0, 0);
|
||||
|
||||
#endif /* __AVX2__ */
|
||||
|
||||
#else /* __AVX512F__ */
|
||||
|
||||
#include <immintrin.h>
|
||||
|
||||
#define ror64(x, n) _mm512_ror_epi64((x), (n))
|
||||
|
||||
static __m512i muladd(__m512i x, __m512i y)
|
||||
{
|
||||
__m512i z = _mm512_mul_epu32(x, y);
|
||||
return _mm512_add_epi64(_mm512_add_epi64(x, y), _mm512_add_epi64(z, z));
|
||||
}
|
||||
|
||||
#define G1(A0, B0, C0, D0, A1, B1, C1, D1) \
|
||||
do { \
|
||||
A0 = muladd(A0, B0); \
|
||||
A1 = muladd(A1, B1); \
|
||||
\
|
||||
D0 = _mm512_xor_si512(D0, A0); \
|
||||
D1 = _mm512_xor_si512(D1, A1); \
|
||||
\
|
||||
D0 = ror64(D0, 32); \
|
||||
D1 = ror64(D1, 32); \
|
||||
\
|
||||
C0 = muladd(C0, D0); \
|
||||
C1 = muladd(C1, D1); \
|
||||
\
|
||||
B0 = _mm512_xor_si512(B0, C0); \
|
||||
B1 = _mm512_xor_si512(B1, C1); \
|
||||
\
|
||||
B0 = ror64(B0, 24); \
|
||||
B1 = ror64(B1, 24); \
|
||||
} while ((void)0, 0)
|
||||
|
||||
#define G2(A0, B0, C0, D0, A1, B1, C1, D1) \
|
||||
do { \
|
||||
A0 = muladd(A0, B0); \
|
||||
A1 = muladd(A1, B1); \
|
||||
\
|
||||
D0 = _mm512_xor_si512(D0, A0); \
|
||||
D1 = _mm512_xor_si512(D1, A1); \
|
||||
\
|
||||
D0 = ror64(D0, 16); \
|
||||
D1 = ror64(D1, 16); \
|
||||
\
|
||||
C0 = muladd(C0, D0); \
|
||||
C1 = muladd(C1, D1); \
|
||||
\
|
||||
B0 = _mm512_xor_si512(B0, C0); \
|
||||
B1 = _mm512_xor_si512(B1, C1); \
|
||||
\
|
||||
B0 = ror64(B0, 63); \
|
||||
B1 = ror64(B1, 63); \
|
||||
} while ((void)0, 0)
|
||||
|
||||
#define DIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1) \
|
||||
do { \
|
||||
B0 = _mm512_permutex_epi64(B0, _MM_SHUFFLE(0, 3, 2, 1)); \
|
||||
B1 = _mm512_permutex_epi64(B1, _MM_SHUFFLE(0, 3, 2, 1)); \
|
||||
\
|
||||
C0 = _mm512_permutex_epi64(C0, _MM_SHUFFLE(1, 0, 3, 2)); \
|
||||
C1 = _mm512_permutex_epi64(C1, _MM_SHUFFLE(1, 0, 3, 2)); \
|
||||
\
|
||||
D0 = _mm512_permutex_epi64(D0, _MM_SHUFFLE(2, 1, 0, 3)); \
|
||||
D1 = _mm512_permutex_epi64(D1, _MM_SHUFFLE(2, 1, 0, 3)); \
|
||||
} while ((void)0, 0)
|
||||
|
||||
#define UNDIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1) \
|
||||
do { \
|
||||
B0 = _mm512_permutex_epi64(B0, _MM_SHUFFLE(2, 1, 0, 3)); \
|
||||
B1 = _mm512_permutex_epi64(B1, _MM_SHUFFLE(2, 1, 0, 3)); \
|
||||
\
|
||||
C0 = _mm512_permutex_epi64(C0, _MM_SHUFFLE(1, 0, 3, 2)); \
|
||||
C1 = _mm512_permutex_epi64(C1, _MM_SHUFFLE(1, 0, 3, 2)); \
|
||||
\
|
||||
D0 = _mm512_permutex_epi64(D0, _MM_SHUFFLE(0, 3, 2, 1)); \
|
||||
D1 = _mm512_permutex_epi64(D1, _MM_SHUFFLE(0, 3, 2, 1)); \
|
||||
} while ((void)0, 0)
|
||||
|
||||
#define BLAKE2_ROUND(A0, B0, C0, D0, A1, B1, C1, D1) \
|
||||
do { \
|
||||
G1(A0, B0, C0, D0, A1, B1, C1, D1); \
|
||||
G2(A0, B0, C0, D0, A1, B1, C1, D1); \
|
||||
\
|
||||
DIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1); \
|
||||
\
|
||||
G1(A0, B0, C0, D0, A1, B1, C1, D1); \
|
||||
G2(A0, B0, C0, D0, A1, B1, C1, D1); \
|
||||
\
|
||||
UNDIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1); \
|
||||
} while ((void)0, 0)
|
||||
|
||||
#define SWAP_HALVES(A0, A1) \
|
||||
do { \
|
||||
__m512i t0, t1; \
|
||||
t0 = _mm512_shuffle_i64x2(A0, A1, _MM_SHUFFLE(1, 0, 1, 0)); \
|
||||
t1 = _mm512_shuffle_i64x2(A0, A1, _MM_SHUFFLE(3, 2, 3, 2)); \
|
||||
A0 = t0; \
|
||||
A1 = t1; \
|
||||
} while((void)0, 0)
|
||||
|
||||
#define SWAP_QUARTERS(A0, A1) \
|
||||
do { \
|
||||
SWAP_HALVES(A0, A1); \
|
||||
A0 = _mm512_permutexvar_epi64(_mm512_setr_epi64(0, 1, 4, 5, 2, 3, 6, 7), A0); \
|
||||
A1 = _mm512_permutexvar_epi64(_mm512_setr_epi64(0, 1, 4, 5, 2, 3, 6, 7), A1); \
|
||||
} while((void)0, 0)
|
||||
|
||||
#define UNSWAP_QUARTERS(A0, A1) \
|
||||
do { \
|
||||
A0 = _mm512_permutexvar_epi64(_mm512_setr_epi64(0, 1, 4, 5, 2, 3, 6, 7), A0); \
|
||||
A1 = _mm512_permutexvar_epi64(_mm512_setr_epi64(0, 1, 4, 5, 2, 3, 6, 7), A1); \
|
||||
SWAP_HALVES(A0, A1); \
|
||||
} while((void)0, 0)
|
||||
|
||||
#define BLAKE2_ROUND_1(A0, C0, B0, D0, A1, C1, B1, D1) \
|
||||
do { \
|
||||
SWAP_HALVES(A0, B0); \
|
||||
SWAP_HALVES(C0, D0); \
|
||||
SWAP_HALVES(A1, B1); \
|
||||
SWAP_HALVES(C1, D1); \
|
||||
BLAKE2_ROUND(A0, B0, C0, D0, A1, B1, C1, D1); \
|
||||
SWAP_HALVES(A0, B0); \
|
||||
SWAP_HALVES(C0, D0); \
|
||||
SWAP_HALVES(A1, B1); \
|
||||
SWAP_HALVES(C1, D1); \
|
||||
} while ((void)0, 0)
|
||||
|
||||
#define BLAKE2_ROUND_2(A0, A1, B0, B1, C0, C1, D0, D1) \
|
||||
do { \
|
||||
SWAP_QUARTERS(A0, A1); \
|
||||
SWAP_QUARTERS(B0, B1); \
|
||||
SWAP_QUARTERS(C0, C1); \
|
||||
SWAP_QUARTERS(D0, D1); \
|
||||
BLAKE2_ROUND(A0, B0, C0, D0, A1, B1, C1, D1); \
|
||||
UNSWAP_QUARTERS(A0, A1); \
|
||||
UNSWAP_QUARTERS(B0, B1); \
|
||||
UNSWAP_QUARTERS(C0, C1); \
|
||||
UNSWAP_QUARTERS(D0, D1); \
|
||||
} while ((void)0, 0)
|
||||
|
||||
#endif /* __AVX512F__ */
|
||||
#endif /* BLAKE_ROUND_MKA_OPT_H */
|
|
@ -1,3 +1,20 @@
|
|||
/*
|
||||
* Argon2 reference source code package - reference C implementations
|
||||
*
|
||||
* Copyright 2015
|
||||
* Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
|
||||
*
|
||||
* You may use this work under the terms of a Creative Commons CC0 1.0
|
||||
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
|
||||
* these licenses can be found at:
|
||||
*
|
||||
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
|
||||
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* You should have received a copy of both of these licenses along with this
|
||||
* software. If not, they may be obtained at the above URLs.
|
||||
*/
|
||||
|
||||
#ifndef BLAKE_ROUND_MKA_H
|
||||
#define BLAKE_ROUND_MKA_H
|
||||
|
23
stratum/algos/blake2b.c
Normal file
23
stratum/algos/blake2b.c
Normal file
|
@ -0,0 +1,23 @@
|
|||
/**
|
||||
* Blake2-B Implementation
|
||||
* tpruvot@github 2016-2018
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <sha3/blake2b.h>
|
||||
#include <sha3/sph_types.h>
|
||||
|
||||
void blake2b_hash(const char* input, char* output, uint32_t len)
|
||||
{
|
||||
uint32_t ALIGN(64) hash[8];
|
||||
blake2b_ctx ctx;
|
||||
|
||||
blake2b_init(&ctx, 32, NULL, 0);
|
||||
blake2b_update(&ctx, input, len);
|
||||
blake2b_final(&ctx, hash);
|
||||
|
||||
memcpy(output, hash, 32);
|
||||
}
|
||||
|
16
stratum/algos/blake2b.h
Normal file
16
stratum/algos/blake2b.h
Normal file
|
@ -0,0 +1,16 @@
|
|||
#ifndef BLAKE2B_H
|
||||
#define BLAKE2B_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
void blake2b_hash(const char* input, char* output, uint32_t len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
4
stratum/algos/common.h
Normal file
4
stratum/algos/common.h
Normal file
|
@ -0,0 +1,4 @@
|
|||
#define _ALIGN(x) __attribute__ ((aligned(x)))
|
||||
|
||||
extern void debuglog_hex(void *data, int len);
|
||||
|
29
stratum/algos/deep.c
Normal file
29
stratum/algos/deep.c
Normal file
|
@ -0,0 +1,29 @@
|
|||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <sha3/sph_luffa.h>
|
||||
#include <sha3/sph_cubehash.h>
|
||||
#include <sha3/sph_echo.h>
|
||||
|
||||
void deep_hash(const char* input, char* output, uint32_t len)
|
||||
{
|
||||
sph_luffa512_context ctx_luffa;
|
||||
sph_cubehash512_context ctx_cubehash;
|
||||
sph_echo512_context ctx_echo;
|
||||
|
||||
char hash1[64], hash2[64];
|
||||
|
||||
sph_luffa512_init(&ctx_luffa);
|
||||
sph_luffa512(&ctx_luffa, (const void*) input, len);
|
||||
sph_luffa512_close(&ctx_luffa, (void*) &hash1);
|
||||
|
||||
sph_cubehash512_init(&ctx_cubehash);
|
||||
sph_cubehash512(&ctx_cubehash, (const void*) &hash1, 64);
|
||||
sph_cubehash512_close(&ctx_cubehash, (void*) &hash2);
|
||||
|
||||
sph_echo512_init(&ctx_echo);
|
||||
sph_echo512(&ctx_echo, (const void*) &hash2, 64);
|
||||
sph_echo512_close(&ctx_echo, (void*) &hash1);
|
||||
|
||||
memcpy(output, &hash1, 32);
|
||||
}
|
17
stratum/algos/deep.h
Normal file
17
stratum/algos/deep.h
Normal file
|
@ -0,0 +1,17 @@
|
|||
#ifndef DEEP_H
|
||||
#define DEEP_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
void deep_hash(const char* input, char* output, uint32_t len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
157
stratum/algos/exosis.c
Normal file
157
stratum/algos/exosis.c
Normal file
|
@ -0,0 +1,157 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define HASH_FUNC_BASE_TIMESTAMP 1538556426 // Exosis: Genesis Timestamp
|
||||
#define HASH_FUNC_COUNT 8
|
||||
#define HASH_FUNC_COUNT_PERMUTATIONS 40320
|
||||
|
||||
#include <sha3/sph_blake.h>
|
||||
#include <sha3/sph_bmw.h>
|
||||
#include <sha3/sph_groestl.h>
|
||||
#include <sha3/sph_jh.h>
|
||||
#include <sha3/sph_keccak.h>
|
||||
#include <sha3/sph_skein.h>
|
||||
#include <sha3/sph_luffa.h>
|
||||
#include <sha3/sph_cubehash.h>
|
||||
|
||||
|
||||
#define _ALIGN(x) __attribute__ ((aligned(x)))
|
||||
|
||||
// helpers
|
||||
inline void swap(int *a, int *b) {
|
||||
int c = *a;
|
||||
*a = *b;
|
||||
*b = c;
|
||||
}
|
||||
|
||||
static void reverse(int *pbegin, int *pend) {
|
||||
while ( (pbegin != pend) && (pbegin != --pend) )
|
||||
swap(pbegin++, pend);
|
||||
}
|
||||
|
||||
static void next_permutation(int *pbegin, int *pend) {
|
||||
if (pbegin == pend)
|
||||
return;
|
||||
|
||||
int *i = pbegin;
|
||||
++i;
|
||||
if (i == pend)
|
||||
return;
|
||||
|
||||
i = pend;
|
||||
--i;
|
||||
|
||||
while (1) {
|
||||
int *j = i;
|
||||
--i;
|
||||
|
||||
if (*i < *j) {
|
||||
int *k = pend;
|
||||
|
||||
while (!(*i < *--k))
|
||||
/* pass */;
|
||||
|
||||
swap(i, k);
|
||||
reverse(j, pend);
|
||||
return; // true
|
||||
}
|
||||
|
||||
if (i == pbegin) {
|
||||
reverse(pbegin, pend);
|
||||
return; // false
|
||||
}
|
||||
}
|
||||
}
|
||||
// helpers
|
||||
|
||||
void exosis_hash(const char* input, char* output, uint32_t len)
|
||||
{
|
||||
uint32_t _ALIGN(64) hash[16 * HASH_FUNC_COUNT];
|
||||
uint32_t *hashA, *hashB;
|
||||
uint32_t dataLen = 64;
|
||||
uint32_t *work_data = (uint32_t *)input;
|
||||
const uint32_t timestamp = work_data[17];
|
||||
|
||||
sph_blake512_context ctx_blake;
|
||||
sph_bmw512_context ctx_bmw;
|
||||
sph_groestl512_context ctx_groestl;
|
||||
sph_skein512_context ctx_skein;
|
||||
sph_jh512_context ctx_jh;
|
||||
sph_keccak512_context ctx_keccak;
|
||||
sph_luffa512_context ctx_luffa;
|
||||
sph_cubehash512_context ctx_cubehash;
|
||||
|
||||
// We want to permute algorithms. To get started we
|
||||
// initialize an array with a sorted sequence of unique
|
||||
// integers where every integer represents its own algorithm.
|
||||
uint32_t permutation[HASH_FUNC_COUNT];
|
||||
for (uint32_t i = 0; i < HASH_FUNC_COUNT; i++) {
|
||||
permutation[i]=i;
|
||||
}
|
||||
|
||||
// Compute the next permuation
|
||||
uint32_t steps = (timestamp - HASH_FUNC_BASE_TIMESTAMP) % HASH_FUNC_COUNT_PERMUTATIONS;
|
||||
for (uint32_t i = 0; i < steps; i++) {
|
||||
next_permutation(permutation, permutation + HASH_FUNC_COUNT);
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < HASH_FUNC_COUNT; i++) {
|
||||
if (i == 0) {
|
||||
dataLen = len;
|
||||
hashA = work_data;
|
||||
} else {
|
||||
dataLen = 64;
|
||||
hashA = &hash[16 * (i - 1)];
|
||||
}
|
||||
hashB = &hash[16 * i];
|
||||
|
||||
switch(permutation[i]) {
|
||||
case 0:
|
||||
sph_blake512_init(&ctx_blake);
|
||||
sph_blake512(&ctx_blake, hashA, dataLen);
|
||||
sph_blake512_close(&ctx_blake, hashB);
|
||||
break;
|
||||
case 1:
|
||||
sph_bmw512_init(&ctx_bmw);
|
||||
sph_bmw512(&ctx_bmw, hashA, dataLen);
|
||||
sph_bmw512_close(&ctx_bmw, hashB);
|
||||
break;
|
||||
case 2:
|
||||
sph_groestl512_init(&ctx_groestl);
|
||||
sph_groestl512(&ctx_groestl, hashA, dataLen);
|
||||
sph_groestl512_close(&ctx_groestl, hashB);
|
||||
break;
|
||||
case 3:
|
||||
sph_skein512_init(&ctx_skein);
|
||||
sph_skein512(&ctx_skein, hashA, dataLen);
|
||||
sph_skein512_close(&ctx_skein, hashB);
|
||||
break;
|
||||
case 4:
|
||||
sph_jh512_init(&ctx_jh);
|
||||
sph_jh512(&ctx_jh, hashA, dataLen);
|
||||
sph_jh512_close(&ctx_jh, hashB);
|
||||
break;
|
||||
case 5:
|
||||
sph_keccak512_init(&ctx_keccak);
|
||||
sph_keccak512(&ctx_keccak, hashA, dataLen);
|
||||
sph_keccak512_close(&ctx_keccak, hashB);
|
||||
break;
|
||||
case 6:
|
||||
sph_luffa512_init(&ctx_luffa);
|
||||
sph_luffa512(&ctx_luffa, hashA, dataLen);
|
||||
sph_luffa512_close(&ctx_luffa, hashB);
|
||||
break;
|
||||
case 7:
|
||||
sph_cubehash512_init(&ctx_cubehash);
|
||||
sph_cubehash512(&ctx_cubehash, hashA, dataLen);
|
||||
sph_cubehash512_close(&ctx_cubehash, hashB);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(output, &hash[16 * (HASH_FUNC_COUNT - 1)], 32);
|
||||
}
|
||||
|
16
stratum/algos/exosis.h
Normal file
16
stratum/algos/exosis.h
Normal file
|
@ -0,0 +1,16 @@
|
|||
#ifndef EXOSIS_H
|
||||
#define EXOSIS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
void exosis_hash(const char* input, char* output, uint32_t len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
180
stratum/algos/hex.c
Normal file
180
stratum/algos/hex.c
Normal file
|
@ -0,0 +1,180 @@
|
|||
// Copyright (c) 2018 The XDNA Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <memory.h>
|
||||
|
||||
#include "hex.h"
|
||||
|
||||
#include "../sha3/sph_blake.h"
|
||||
#include "../sha3/sph_bmw.h"
|
||||
#include "../sha3/sph_groestl.h"
|
||||
#include "../sha3/sph_skein.h"
|
||||
#include "../sha3/sph_jh.h"
|
||||
#include "../sha3/sph_keccak.h"
|
||||
|
||||
#include "../sha3/sph_luffa.h"
|
||||
#include "../sha3/sph_cubehash.h"
|
||||
#include "../sha3/sph_shavite.h"
|
||||
#include "../sha3/sph_simd.h"
|
||||
#include "../sha3/sph_echo.h"
|
||||
|
||||
#include "../sha3/sph_hamsi.h"
|
||||
#include "../sha3/sph_fugue.h"
|
||||
#include "../sha3/sph_shabal.h"
|
||||
#include "../sha3/sph_whirlpool.h"
|
||||
#include "../sha3/sph_sha2.h"
|
||||
|
||||
enum Algo {
|
||||
BLAKE = 0,
|
||||
BMW,
|
||||
GROESTL,
|
||||
JH,
|
||||
KECCAK,
|
||||
SKEIN,
|
||||
LUFFA,
|
||||
CUBEHASH,
|
||||
SHAVITE,
|
||||
SIMD,
|
||||
ECHO,
|
||||
HAMSI,
|
||||
FUGUE,
|
||||
SHABAL,
|
||||
WHIRLPOOL,
|
||||
SHA512,
|
||||
HASH_FUNC_COUNT
|
||||
};
|
||||
|
||||
static const int TOTAL_CYCLES = 16;
|
||||
|
||||
static uint8_t get_first_algo(const uint32_t* prevblock) {
|
||||
uint8_t* data = (uint8_t*)prevblock;
|
||||
return data[7] >> 4;
|
||||
}
|
||||
|
||||
void hex_hash(const char* input, char* output, uint32_t len)
|
||||
{
|
||||
unsigned char hash[128];
|
||||
uint8_t curr_algo;
|
||||
|
||||
sph_blake512_context ctx_blake;
|
||||
sph_bmw512_context ctx_bmw;
|
||||
sph_groestl512_context ctx_groestl;
|
||||
sph_jh512_context ctx_jh;
|
||||
sph_keccak512_context ctx_keccak;
|
||||
sph_skein512_context ctx_skein;
|
||||
sph_luffa512_context ctx_luffa;
|
||||
sph_cubehash512_context ctx_cubehash;
|
||||
sph_shavite512_context ctx_shavite;
|
||||
sph_simd512_context ctx_simd;
|
||||
sph_echo512_context ctx_echo;
|
||||
sph_hamsi512_context ctx_hamsi;
|
||||
sph_fugue512_context ctx_fugue;
|
||||
sph_shabal512_context ctx_shabal;
|
||||
sph_whirlpool_context ctx_whirlpool;
|
||||
sph_sha512_context ctx_sha512;
|
||||
|
||||
const void *in = input;
|
||||
int size = len;
|
||||
|
||||
uint32_t *in32 = (uint32_t*) input;
|
||||
|
||||
// initial algo = first digit of prev block hashorder (cheers, x16r)
|
||||
curr_algo = get_first_algo(&in32[1]);
|
||||
|
||||
for (int i = 0; i < TOTAL_CYCLES; i++)
|
||||
{
|
||||
// Only 4 test algos yet
|
||||
switch (curr_algo) {
|
||||
case BLAKE:
|
||||
sph_blake512_init(&ctx_blake);
|
||||
sph_blake512(&ctx_blake, in, size);
|
||||
sph_blake512_close(&ctx_blake, hash);
|
||||
break;
|
||||
case BMW:
|
||||
sph_bmw512_init(&ctx_bmw);
|
||||
sph_bmw512(&ctx_bmw, in, size);
|
||||
sph_bmw512_close(&ctx_bmw, hash);
|
||||
break;
|
||||
case GROESTL:
|
||||
sph_groestl512_init(&ctx_groestl);
|
||||
sph_groestl512(&ctx_groestl, in, size);
|
||||
sph_groestl512_close(&ctx_groestl, hash);
|
||||
break;
|
||||
case JH:
|
||||
sph_jh512_init(&ctx_jh);
|
||||
sph_jh512(&ctx_jh, in, size);
|
||||
sph_jh512_close(&ctx_jh, hash);
|
||||
break;
|
||||
case KECCAK:
|
||||
sph_keccak512_init(&ctx_keccak);
|
||||
sph_keccak512(&ctx_keccak, in, size);
|
||||
sph_keccak512_close(&ctx_keccak, hash);
|
||||
break;
|
||||
case SKEIN:
|
||||
sph_skein512_init(&ctx_skein);
|
||||
sph_skein512(&ctx_skein, in, size);
|
||||
sph_skein512_close(&ctx_skein, hash);
|
||||
break;
|
||||
case LUFFA:
|
||||
sph_luffa512_init(&ctx_luffa);
|
||||
sph_luffa512(&ctx_luffa, in, size);
|
||||
sph_luffa512_close(&ctx_luffa, hash);
|
||||
break;
|
||||
case CUBEHASH:
|
||||
sph_cubehash512_init(&ctx_cubehash);
|
||||
sph_cubehash512(&ctx_cubehash, in, size);
|
||||
sph_cubehash512_close(&ctx_cubehash, hash);
|
||||
break;
|
||||
case SHAVITE:
|
||||
sph_shavite512_init(&ctx_shavite);
|
||||
sph_shavite512(&ctx_shavite, in, size);
|
||||
sph_shavite512_close(&ctx_shavite, hash);
|
||||
break;
|
||||
case SIMD:
|
||||
sph_simd512_init(&ctx_simd);
|
||||
sph_simd512(&ctx_simd, in, size);
|
||||
sph_simd512_close(&ctx_simd, hash);
|
||||
break;
|
||||
|
||||
case ECHO:
|
||||
sph_echo512_init(&ctx_echo);
|
||||
sph_echo512(&ctx_echo, in, size);
|
||||
sph_echo512_close(&ctx_echo, hash);
|
||||
break;
|
||||
case HAMSI:
|
||||
sph_hamsi512_init(&ctx_hamsi);
|
||||
sph_hamsi512(&ctx_hamsi, in, size);
|
||||
sph_hamsi512_close(&ctx_hamsi, hash);
|
||||
break;
|
||||
case FUGUE:
|
||||
sph_fugue512_init(&ctx_fugue);
|
||||
sph_fugue512(&ctx_fugue, in, size);
|
||||
sph_fugue512_close(&ctx_fugue, hash);
|
||||
break;
|
||||
case SHABAL:
|
||||
sph_shabal512_init(&ctx_shabal);
|
||||
sph_shabal512(&ctx_shabal, in, size);
|
||||
sph_shabal512_close(&ctx_shabal, hash);
|
||||
break;
|
||||
case WHIRLPOOL:
|
||||
sph_whirlpool_init(&ctx_whirlpool);
|
||||
sph_whirlpool(&ctx_whirlpool, in, size);
|
||||
sph_whirlpool_close(&ctx_whirlpool, hash);
|
||||
break;
|
||||
case SHA512:
|
||||
sph_sha512_init(&ctx_sha512);
|
||||
sph_sha512(&ctx_sha512,(const void*) in, size);
|
||||
sph_sha512_close(&ctx_sha512,(void*) hash);
|
||||
break;
|
||||
}
|
||||
// next algos = first digit on prev hash
|
||||
curr_algo = (uint8_t)hash[0] % HASH_FUNC_COUNT;
|
||||
in = (void*)hash;
|
||||
size = 64;
|
||||
}
|
||||
|
||||
memcpy(output, hash, 32);
|
||||
}
|
20
stratum/algos/hex.h
Normal file
20
stratum/algos/hex.h
Normal file
|
@ -0,0 +1,20 @@
|
|||
// Copyright (c) 2018 The XDNA Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifndef HEXHASH_H
|
||||
#define HEXHASH_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void hex_hash(const char* input, char* output, uint32_t len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // HEXHASH_H
|
218
stratum/algos/hmq17.c
Normal file
218
stratum/algos/hmq17.c
Normal file
|
@ -0,0 +1,218 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <sha3/sph_blake.h>
|
||||
#include <sha3/sph_bmw.h>
|
||||
#include <sha3/sph_groestl.h>
|
||||
#include <sha3/sph_jh.h>
|
||||
#include <sha3/sph_keccak.h>
|
||||
#include <sha3/sph_skein.h>
|
||||
#include <sha3/sph_luffa.h>
|
||||
#include <sha3/sph_cubehash.h>
|
||||
#include <sha3/sph_shavite.h>
|
||||
#include <sha3/sph_simd.h>
|
||||
#include <sha3/sph_echo.h>
|
||||
#include <sha3/sph_hamsi.h>
|
||||
#include <sha3/sph_fugue.h>
|
||||
#include <sha3/sph_shabal.h>
|
||||
#include <sha3/sph_whirlpool.h>
|
||||
#include <sha3/sph_sha2.h>
|
||||
#include <sha3/sph_haval.h>
|
||||
|
||||
typedef struct
|
||||
{
|
||||
sph_blake512_context blake1, blake2;
|
||||
sph_bmw512_context bmw1, bmw2, bmw3;
|
||||
sph_groestl512_context groestl1, groestl2;
|
||||
sph_skein512_context skein1, skein2;
|
||||
sph_jh512_context jh1, jh2;
|
||||
sph_keccak512_context keccak1, keccak2;
|
||||
sph_luffa512_context luffa1, luffa2;
|
||||
sph_cubehash512_context cubehash;
|
||||
sph_shavite512_context shavite1, shavite2;
|
||||
sph_simd512_context simd1, simd2;
|
||||
sph_echo512_context echo1, echo2;
|
||||
sph_hamsi512_context hamsi;
|
||||
sph_fugue512_context fugue1, fugue2;
|
||||
sph_shabal512_context shabal;
|
||||
sph_whirlpool_context whirlpool1, whirlpool2, whirlpool3, whirlpool4;
|
||||
sph_sha512_context sha1, sha2;
|
||||
sph_haval256_5_context haval1, haval2;
|
||||
} hmq_contexts;
|
||||
|
||||
static __thread hmq_contexts base_contexts;
|
||||
static __thread int hmq_context_init = 0;
|
||||
|
||||
static void init_contexts(hmq_contexts *ctx)
|
||||
{
|
||||
sph_bmw512_init(&ctx->bmw1);
|
||||
sph_bmw512_init(&ctx->bmw2);
|
||||
sph_bmw512_init(&ctx->bmw2);
|
||||
sph_bmw512_init(&ctx->bmw3);
|
||||
sph_whirlpool_init(&ctx->whirlpool1);
|
||||
sph_whirlpool_init(&ctx->whirlpool2);
|
||||
sph_whirlpool_init(&ctx->whirlpool3);
|
||||
sph_whirlpool_init(&ctx->whirlpool4);
|
||||
sph_groestl512_init(&ctx->groestl1);
|
||||
sph_groestl512_init(&ctx->groestl2);
|
||||
sph_skein512_init(&ctx->skein1);
|
||||
sph_skein512_init(&ctx->skein2);
|
||||
sph_jh512_init(&ctx->jh1);
|
||||
sph_jh512_init(&ctx->jh2);
|
||||
sph_keccak512_init(&ctx->keccak1);
|
||||
sph_keccak512_init(&ctx->keccak2);
|
||||
sph_blake512_init(&ctx->blake1);
|
||||
sph_blake512_init(&ctx->blake2);
|
||||
sph_luffa512_init(&ctx->luffa1);
|
||||
sph_luffa512_init(&ctx->luffa2);
|
||||
sph_cubehash512_init(&ctx->cubehash);
|
||||
sph_shavite512_init(&ctx->shavite1);
|
||||
sph_shavite512_init(&ctx->shavite2);
|
||||
sph_simd512_init(&ctx->simd1);
|
||||
sph_simd512_init(&ctx->simd2);
|
||||
sph_echo512_init(&ctx->echo1);
|
||||
sph_echo512_init(&ctx->echo2);
|
||||
sph_hamsi512_init(&ctx->hamsi);
|
||||
sph_fugue512_init(&ctx->fugue1);
|
||||
sph_fugue512_init(&ctx->fugue2);
|
||||
sph_shabal512_init(&ctx->shabal);
|
||||
sph_sha512_init(&ctx->sha1);
|
||||
sph_sha512_init(&ctx->sha2);
|
||||
sph_haval256_5_init(&ctx->haval1);
|
||||
sph_haval256_5_init(&ctx->haval2);
|
||||
}
|
||||
|
||||
void hmq17_hash(const char* input, char* output, uint32_t len)
|
||||
{
|
||||
uint32_t hash[32];
|
||||
|
||||
const uint32_t mask = 24;
|
||||
|
||||
hmq_contexts ctx;
|
||||
|
||||
if (!hmq_context_init) {
|
||||
init_contexts(&base_contexts);
|
||||
hmq_context_init = 1;
|
||||
}
|
||||
memcpy(&ctx, &base_contexts, sizeof(hmq_contexts));
|
||||
|
||||
sph_bmw512(&ctx.bmw1, input, len);
|
||||
sph_bmw512_close(&ctx.bmw1, hash);
|
||||
|
||||
sph_whirlpool(&ctx.whirlpool1, hash, 64);
|
||||
sph_whirlpool_close(&ctx.whirlpool1, hash);
|
||||
|
||||
if (hash[0] & mask) {
|
||||
sph_groestl512(&ctx.groestl1, hash, 64);
|
||||
sph_groestl512_close(&ctx.groestl1, hash);
|
||||
} else {
|
||||
sph_skein512(&ctx.skein1, hash, 64);
|
||||
sph_skein512_close(&ctx.skein1, hash);
|
||||
}
|
||||
|
||||
sph_jh512(&ctx.jh1, hash, 64);
|
||||
sph_jh512_close(&ctx.jh1, hash);
|
||||
|
||||
sph_keccak512(&ctx.keccak1, hash, 64);
|
||||
sph_keccak512_close(&ctx.keccak1, hash);
|
||||
|
||||
if (hash[0] & mask) {
|
||||
sph_blake512(&ctx.blake1, hash, 64);
|
||||
sph_blake512_close(&ctx.blake1, hash);
|
||||
} else {
|
||||
sph_bmw512 (&ctx.bmw2, hash, 64);
|
||||
sph_bmw512_close(&ctx.bmw2, hash);
|
||||
}
|
||||
|
||||
sph_luffa512(&ctx.luffa1, hash, 64);
|
||||
sph_luffa512_close(&ctx.luffa1, hash);
|
||||
|
||||
sph_cubehash512(&ctx.cubehash, hash, 64);
|
||||
sph_cubehash512_close(&ctx.cubehash, hash);
|
||||
|
||||
if (hash[0] & mask) {
|
||||
sph_keccak512(&ctx.keccak2, hash, 64);
|
||||
sph_keccak512_close(&ctx.keccak2, hash);
|
||||
} else {
|
||||
sph_jh512(&ctx.jh2, hash, 64);
|
||||
sph_jh512_close(&ctx.jh2, hash);
|
||||
}
|
||||
|
||||
sph_shavite512(&ctx.shavite1, hash, 64);
|
||||
sph_shavite512_close(&ctx.shavite1, hash);
|
||||
|
||||
sph_simd512(&ctx.simd1, hash, 64);
|
||||
sph_simd512_close(&ctx.simd1, hash);
|
||||
|
||||
if (hash[0] & mask) {
|
||||
sph_whirlpool(&ctx.whirlpool2, hash, 64);
|
||||
sph_whirlpool_close(&ctx.whirlpool2, hash);
|
||||
} else {
|
||||
sph_haval256_5(&ctx.haval1, hash, 64);
|
||||
sph_haval256_5_close(&ctx.haval1, hash);
|
||||
memset(&hash[8], 0, 32);
|
||||
}
|
||||
|
||||
sph_echo512(&ctx.echo1, hash, 64);
|
||||
sph_echo512_close(&ctx.echo1, hash);
|
||||
|
||||
sph_blake512(&ctx.blake2, hash, 64);
|
||||
sph_blake512_close(&ctx.blake2, hash);
|
||||
|
||||
if (hash[0] & mask) {
|
||||
sph_shavite512(&ctx.shavite2, hash, 64);
|
||||
sph_shavite512_close(&ctx.shavite2, hash);
|
||||
} else {
|
||||
sph_luffa512 (&ctx.luffa2, hash, 64);
|
||||
sph_luffa512_close(&ctx.luffa2, hash);
|
||||
}
|
||||
|
||||
sph_hamsi512(&ctx.hamsi, hash, 64);
|
||||
sph_hamsi512_close(&ctx.hamsi, hash);
|
||||
|
||||
sph_fugue512(&ctx.fugue1, hash, 64);
|
||||
sph_fugue512_close(&ctx.fugue1, hash);
|
||||
|
||||
if (hash[0] & mask) {
|
||||
sph_echo512(&ctx.echo2, hash, 64);
|
||||
sph_echo512_close(&ctx.echo2, hash);
|
||||
} else {
|
||||
sph_simd512(&ctx.simd2, hash, 64);
|
||||
sph_simd512_close(&ctx.simd2, hash);
|
||||
}
|
||||
|
||||
sph_shabal512(&ctx.shabal, hash, 64);
|
||||
sph_shabal512_close(&ctx.shabal, hash);
|
||||
|
||||
sph_whirlpool(&ctx.whirlpool3, hash, 64);
|
||||
sph_whirlpool_close(&ctx.whirlpool3, hash);
|
||||
|
||||
if (hash[0] & mask) {
|
||||
sph_fugue512(&ctx.fugue2, hash, 64);
|
||||
sph_fugue512_close(&ctx.fugue2, hash);
|
||||
} else {
|
||||
sph_sha512(&ctx.sha1, hash, 64);
|
||||
sph_sha512_close(&ctx.sha1, hash);
|
||||
}
|
||||
|
||||
sph_groestl512(&ctx.groestl2, hash, 64);
|
||||
sph_groestl512_close(&ctx.groestl2, hash);
|
||||
|
||||
sph_sha512(&ctx.sha2, hash, 64);
|
||||
sph_sha512_close(&ctx.sha2, hash);
|
||||
|
||||
if (hash[0] & mask) {
|
||||
sph_haval256_5(&ctx.haval2, hash, 64);
|
||||
sph_haval256_5_close(&ctx.haval2, hash);
|
||||
memset(&hash[8], 0, 32);
|
||||
} else {
|
||||
sph_whirlpool(&ctx.whirlpool4, hash, 64);
|
||||
sph_whirlpool_close(&ctx.whirlpool4, hash);
|
||||
}
|
||||
|
||||
sph_bmw512(&ctx.bmw3, hash, 64);
|
||||
sph_bmw512_close(&ctx.bmw3, hash);
|
||||
|
||||
memcpy(output, hash, 32);
|
||||
}
|
16
stratum/algos/hmq17.h
Normal file
16
stratum/algos/hmq17.h
Normal file
|
@ -0,0 +1,16 @@
|
|||
#ifndef HMQ17_H
|
||||
#define HMQ17_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
void hmq17_hash(const char* input, char* output, uint32_t len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
101
stratum/algos/hsr14.c
Normal file
101
stratum/algos/hsr14.c
Normal file
|
@ -0,0 +1,101 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "../sha3/sph_blake.h"
|
||||
#include "../sha3/sph_bmw.h"
|
||||
#include "../sha3/sph_groestl.h"
|
||||
#include "../sha3/sph_jh.h"
|
||||
#include "../sha3/sph_keccak.h"
|
||||
#include "../sha3/sph_skein.h"
|
||||
#include "../sha3/sph_luffa.h"
|
||||
#include "../sha3/sph_cubehash.h"
|
||||
#include "../sha3/sph_shavite.h"
|
||||
#include "../sha3/sph_simd.h"
|
||||
#include "../sha3/sph_echo.h"
|
||||
#include "../sha3/sph_hamsi.h"
|
||||
#include "../sha3/sph_fugue.h"
|
||||
|
||||
#include "sm3.h"
|
||||
|
||||
#include "common.h"
|
||||
|
||||
void hsr_hash(const char* input, char* output, uint32_t len)
|
||||
{
|
||||
sph_blake512_context ctx_blake;
|
||||
sph_bmw512_context ctx_bmw;
|
||||
sph_groestl512_context ctx_groestl;
|
||||
sph_skein512_context ctx_skein;
|
||||
sph_jh512_context ctx_jh;
|
||||
sph_keccak512_context ctx_keccak;
|
||||
sph_luffa512_context ctx_luffa1;
|
||||
sph_cubehash512_context ctx_cubehash1;
|
||||
sph_shavite512_context ctx_shavite1;
|
||||
sph_simd512_context ctx_simd1;
|
||||
sph_echo512_context ctx_echo1;
|
||||
sm3_ctx_t ctx_sm3;
|
||||
sph_hamsi512_context ctx_hamsi1;
|
||||
sph_fugue512_context ctx_fugue1;
|
||||
|
||||
uint8_t _ALIGN(128) hash[64];
|
||||
|
||||
sph_blake512_init(&ctx_blake);
|
||||
sph_blake512(&ctx_blake, input, len);
|
||||
sph_blake512_close(&ctx_blake, hash);
|
||||
|
||||
sph_bmw512_init(&ctx_bmw);
|
||||
sph_bmw512(&ctx_bmw, hash, 64);
|
||||
sph_bmw512_close(&ctx_bmw, hash);
|
||||
|
||||
sph_groestl512_init(&ctx_groestl);
|
||||
sph_groestl512(&ctx_groestl, hash, 64);
|
||||
sph_groestl512_close(&ctx_groestl, hash);
|
||||
|
||||
sph_skein512_init(&ctx_skein);
|
||||
sph_skein512(&ctx_skein, hash, 64);
|
||||
sph_skein512_close (&ctx_skein, hash);
|
||||
|
||||
sph_jh512_init(&ctx_jh);
|
||||
sph_jh512(&ctx_jh, hash, 64);
|
||||
sph_jh512_close(&ctx_jh, hash);
|
||||
|
||||
sph_keccak512_init(&ctx_keccak);
|
||||
sph_keccak512(&ctx_keccak, hash, 64);
|
||||
sph_keccak512_close(&ctx_keccak, hash);
|
||||
|
||||
sph_luffa512_init(&ctx_luffa1);
|
||||
sph_luffa512(&ctx_luffa1, hash, 64);
|
||||
sph_luffa512_close(&ctx_luffa1, hash);
|
||||
|
||||
sph_cubehash512_init(&ctx_cubehash1);
|
||||
sph_cubehash512(&ctx_cubehash1, hash, 64);
|
||||
sph_cubehash512_close(&ctx_cubehash1, hash);
|
||||
|
||||
sph_shavite512_init(&ctx_shavite1);
|
||||
sph_shavite512(&ctx_shavite1, hash, 64);
|
||||
sph_shavite512_close(&ctx_shavite1, hash);
|
||||
|
||||
sph_simd512_init(&ctx_simd1);
|
||||
sph_simd512(&ctx_simd1, hash, 64);
|
||||
sph_simd512_close(&ctx_simd1, hash);
|
||||
|
||||
sph_echo512_init (&ctx_echo1);
|
||||
sph_echo512(&ctx_echo1, hash, 64);
|
||||
sph_echo512_close(&ctx_echo1, hash);
|
||||
|
||||
sm3_init(&ctx_sm3);
|
||||
sm3_update(&ctx_sm3, hash, 64);
|
||||
memset(hash, 0, sizeof hash);
|
||||
sm3_close(&ctx_sm3, hash);
|
||||
|
||||
sph_hamsi512_init(&ctx_hamsi1);
|
||||
sph_hamsi512(&ctx_hamsi1, hash, 64);
|
||||
sph_hamsi512_close(&ctx_hamsi1, hash);
|
||||
|
||||
sph_fugue512_init(&ctx_fugue1);
|
||||
sph_fugue512(&ctx_fugue1, hash, 64);
|
||||
sph_fugue512_close(&ctx_fugue1, hash);
|
||||
|
||||
memcpy(output, hash, 32);
|
||||
}
|
16
stratum/algos/hsr14.h
Normal file
16
stratum/algos/hsr14.h
Normal file
|
@ -0,0 +1,16 @@
|
|||
#ifndef HSR14_H
|
||||
#define HSR14_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
void hsr_hash(const char* input, char* output, uint32_t len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,135 +1,56 @@
|
|||
#include "jha.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "../sha3/sph_blake.h"
|
||||
#include "../sha3/sph_groestl.h"
|
||||
#include "../sha3/sph_jh.h"
|
||||
#include "../sha3/sph_keccak.h"
|
||||
#include "../sha3/sph_skein.h"
|
||||
#include <sha3/sph_blake.h>
|
||||
#include <sha3/sph_groestl.h>
|
||||
#include <sha3/sph_jh.h>
|
||||
#include <sha3/sph_keccak.h>
|
||||
#include <sha3/sph_skein.h>
|
||||
|
||||
#include "jha.h"
|
||||
#include "common.h"
|
||||
|
||||
void jha_hash(const char* input, char* output, uint32_t len) {
|
||||
void jha_hash(const char* input, char* output, uint32_t len)
|
||||
{
|
||||
sph_blake512_context ctx_blake;
|
||||
sph_groestl512_context ctx_groestl;
|
||||
sph_jh512_context ctx_jh;
|
||||
sph_keccak512_context ctx_keccak;
|
||||
sph_skein512_context ctx_skein;
|
||||
|
||||
sph_blake512_context ctx_blake;
|
||||
sph_groestl512_context ctx_groestl;
|
||||
sph_jh512_context ctx_jh;
|
||||
sph_keccak512_context ctx_keccak;
|
||||
sph_skein512_context ctx_skein;
|
||||
uint32_t _ALIGN(64) hash[16];
|
||||
|
||||
uint32_t hash[16];
|
||||
// JHA v8: SHA3 512, on 80 bytes (not 88)
|
||||
sph_keccak512_init(&ctx_keccak);
|
||||
sph_keccak512(&ctx_keccak, input, 80);
|
||||
sph_keccak512_close(&ctx_keccak, (&hash));
|
||||
|
||||
unsigned int round_mask = (
|
||||
(unsigned int)(((unsigned char *)input)[84]) << 0 |
|
||||
(unsigned int)(((unsigned char *)input)[85]) << 8 |
|
||||
(unsigned int)(((unsigned char *)input)[86]) << 16 |
|
||||
(unsigned int)(((unsigned char *)input)[87]) << 24 );
|
||||
// Heavy & Light Pair Loop
|
||||
for (int round = 0; round < 3; round++)
|
||||
{
|
||||
if (hash[0] & 0x01) {
|
||||
sph_groestl512_init(&ctx_groestl);
|
||||
sph_groestl512(&ctx_groestl, (&hash), 64);
|
||||
sph_groestl512_close(&ctx_groestl, (&hash));
|
||||
} else {
|
||||
sph_skein512_init(&ctx_skein);
|
||||
sph_skein512(&ctx_skein, (&hash), 64);
|
||||
sph_skein512_close(&ctx_skein, (&hash));
|
||||
}
|
||||
|
||||
//
|
||||
// JHA V7
|
||||
//
|
||||
if (round_mask == 7) {
|
||||
|
||||
//
|
||||
// Input Hashing with SHA3 512, 88 bytes
|
||||
//
|
||||
sph_keccak512_init(&ctx_keccak);
|
||||
sph_keccak512 (&ctx_keccak, input, 88);
|
||||
sph_keccak512_close(&ctx_keccak, hash);
|
||||
|
||||
//
|
||||
// Variable Rounds Loop
|
||||
//
|
||||
unsigned int rounds = hash[0] & 7;
|
||||
unsigned int round;
|
||||
for (round = 0; round < rounds; round++) {
|
||||
switch (hash[0] & 3) {
|
||||
case 0:
|
||||
sph_blake512_init(&ctx_blake);
|
||||
sph_blake512 (&ctx_blake, hash, 64);
|
||||
sph_blake512_close(&ctx_blake, hash);
|
||||
break;
|
||||
case 1:
|
||||
sph_groestl512_init(&ctx_groestl);
|
||||
sph_groestl512 (&ctx_groestl, hash, 64);
|
||||
sph_groestl512_close(&ctx_groestl, hash);
|
||||
break;
|
||||
case 2:
|
||||
sph_jh512_init(&ctx_jh);
|
||||
sph_jh512 (&ctx_jh, hash, 64);
|
||||
sph_jh512_close(&ctx_jh, hash);
|
||||
break;
|
||||
case 3:
|
||||
sph_skein512_init(&ctx_skein);
|
||||
sph_skein512 (&ctx_skein, hash, 64);
|
||||
sph_skein512_close(&ctx_skein, hash);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Return 256bit(32x8)
|
||||
//
|
||||
memcpy(output, hash, 32);
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
// JHA V8
|
||||
//
|
||||
else if (round_mask == 8) {
|
||||
|
||||
//
|
||||
// Input Hashing with SHA3 512, 80 bytes
|
||||
//
|
||||
sph_keccak512_init(&ctx_keccak);
|
||||
sph_keccak512 (&ctx_keccak, input, 80);
|
||||
sph_keccak512_close(&ctx_keccak, (&hash));
|
||||
|
||||
//
|
||||
// Heavy & Light Pair Loop
|
||||
//
|
||||
unsigned int round;
|
||||
for (round = 0; round < 3; round++) {
|
||||
if (hash[0] & 0x01) {
|
||||
sph_groestl512_init(&ctx_groestl);
|
||||
sph_groestl512 (&ctx_groestl, (&hash), 64);
|
||||
sph_groestl512_close(&ctx_groestl, (&hash));
|
||||
}
|
||||
else {
|
||||
sph_skein512_init(&ctx_skein);
|
||||
sph_skein512 (&ctx_skein, (&hash), 64);
|
||||
sph_skein512_close(&ctx_skein, (&hash));
|
||||
}
|
||||
if (hash[0] & 0x01) {
|
||||
sph_blake512_init(&ctx_blake);
|
||||
sph_blake512 (&ctx_blake, (&hash), 64);
|
||||
sph_blake512_close(&ctx_blake, (&hash));
|
||||
}
|
||||
else {
|
||||
sph_jh512_init(&ctx_jh);
|
||||
sph_jh512 (&ctx_jh, (&hash), 64);
|
||||
sph_jh512_close(&ctx_jh, (&hash));
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Return 256bit(32x8)
|
||||
//
|
||||
memcpy(output, hash, 32);
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
// Wrong Round Mask Data
|
||||
//
|
||||
else {
|
||||
|
||||
memset(output, 0xFF, 32);
|
||||
|
||||
}
|
||||
if (hash[0] & 0x01) {
|
||||
sph_blake512_init(&ctx_blake);
|
||||
sph_blake512(&ctx_blake, (&hash), 64);
|
||||
sph_blake512_close(&ctx_blake, (&hash));
|
||||
} else {
|
||||
sph_jh512_init(&ctx_jh);
|
||||
sph_jh512(&ctx_jh, (&hash), 64);
|
||||
sph_jh512_close(&ctx_jh, (&hash));
|
||||
}
|
||||
}
|
||||
|
||||
// Return 256 bits (32x8)
|
||||
memcpy(output, hash, 32);
|
||||
}
|
||||
|
|
36
stratum/algos/lbk3.c
Normal file
36
stratum/algos/lbk3.c
Normal file
|
@ -0,0 +1,36 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <sha3/sph_blake.h>
|
||||
#include <sha3/sph_bmw.h>
|
||||
#include <sha3/sph_keccak.h>
|
||||
|
||||
#define _ALIGN(x) __attribute__ ((aligned(x)))
|
||||
|
||||
extern uint64_t lbk3_height;
|
||||
|
||||
void lbk3_hash(const char* input, char* output, uint32_t len)
|
||||
{
|
||||
sph_bmw256_context ctx_bmw;
|
||||
sph_blake256_context ctx_blake;
|
||||
sph_keccak256_context ctx_keccak;
|
||||
|
||||
uint8_t _ALIGN(128) hash[96];
|
||||
memset(&hash[32], 0, 64);
|
||||
|
||||
sph_bmw256_init(&ctx_bmw);
|
||||
sph_bmw256 (&ctx_bmw, input, 80);
|
||||
sph_bmw256_close(&ctx_bmw, &hash[0]);
|
||||
|
||||
sph_blake256_init(&ctx_blake);
|
||||
sph_blake256 (&ctx_blake, &hash[0], 64);
|
||||
sph_blake256_close(&ctx_blake, &hash[32]);
|
||||
|
||||
sph_keccak256_init(&ctx_keccak);
|
||||
sph_keccak256 (&ctx_keccak, &hash[32], 64);
|
||||
sph_keccak256_close(&ctx_keccak, &hash[64]);
|
||||
|
||||
memcpy(output, &hash[64], 32);
|
||||
}
|
16
stratum/algos/lbk3.h
Normal file
16
stratum/algos/lbk3.h
Normal file
|
@ -0,0 +1,16 @@
|
|||
#ifndef LBK3_H
|
||||
#define LBK3_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
void lbk3_hash(const char* input, char* output, uint32_t len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
68
stratum/algos/lyra2v3.c
Normal file
68
stratum/algos/lyra2v3.c
Normal file
|
@ -0,0 +1,68 @@
|
|||
/*-
|
||||
* Copyright(or left) 2019 YiiMP
|
||||
*
|
||||
* 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 <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "../sha3/sph_blake.h"
|
||||
#include "../sha3/sph_cubehash.h"
|
||||
#include "../sha3/sph_bmw.h"
|
||||
|
||||
#include "Lyra2.h"
|
||||
|
||||
void lyra2v3_hash(const char* input, char* output, uint32_t len)
|
||||
{
|
||||
uint32_t hash[8], hashB[8];
|
||||
|
||||
sph_blake256_context ctx_blake;
|
||||
sph_cubehash256_context ctx_cubehash;
|
||||
sph_bmw256_context ctx_bmw;
|
||||
|
||||
sph_blake256_set_rounds(14);
|
||||
|
||||
sph_blake256_init(&ctx_blake);
|
||||
sph_blake256(&ctx_blake, input, len); /* 80 */
|
||||
sph_blake256_close(&ctx_blake, hash);
|
||||
|
||||
LYRA2_3(hashB, 32, hash, 32, hash, 32, 1, 4, 4);
|
||||
|
||||
sph_cubehash256_init(&ctx_cubehash);
|
||||
sph_cubehash256(&ctx_cubehash, hashB, 32);
|
||||
sph_cubehash256_close(&ctx_cubehash, hash);
|
||||
|
||||
LYRA2_3(hashB, 32, hash, 32, hash, 32, 1, 4, 4);
|
||||
|
||||
sph_bmw256_init(&ctx_bmw);
|
||||
sph_bmw256(&ctx_bmw, hashB, 32);
|
||||
sph_bmw256_close(&ctx_bmw, hash);
|
||||
|
||||
memcpy(output, hash, 32);
|
||||
}
|
||||
|
16
stratum/algos/lyra2v3.h
Normal file
16
stratum/algos/lyra2v3.h
Normal file
|
@ -0,0 +1,16 @@
|
|||
#ifndef LYRA2V3_H
|
||||
#define LYRA2V3_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
void lyra2v3_hash(const char* input, char* output, uint32_t len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
39
stratum/algos/lyra2z.c
Normal file
39
stratum/algos/lyra2z.c
Normal file
|
@ -0,0 +1,39 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "Lyra2-z.h"
|
||||
|
||||
#include <sha3/sph_blake.h>
|
||||
|
||||
#define _ALIGN(x) __attribute__ ((aligned(x)))
|
||||
|
||||
extern uint64_t lyra2z_height;
|
||||
|
||||
void lyra2z_hash(const char* input, char* output, uint32_t len)
|
||||
{
|
||||
uint32_t _ALIGN(64) hashB[8], hash[8];
|
||||
sph_blake256_context ctx_blake;
|
||||
/*
|
||||
uint64_t height = lyra2z_height;
|
||||
// initial implementation was pure lyra2 (no blake)
|
||||
|
||||
if (height < 100) {
|
||||
fprintf(stderr, "submit error, height=%u, len=%u\n", (uint32_t) height, len);
|
||||
memset(hash, 0xff, 32);
|
||||
return;
|
||||
}
|
||||
LYRA2z((void*)hash, 32, (void*)input, len, (void*)input, len, 2, height, 256);
|
||||
*/
|
||||
sph_blake256_set_rounds(14);
|
||||
|
||||
sph_blake256_init(&ctx_blake);
|
||||
sph_blake256(&ctx_blake, input, len);
|
||||
sph_blake256_close(&ctx_blake, hashB);
|
||||
|
||||
LYRA2z(hash, 32, hashB, 32, hashB, 32, 8, 8, 8);
|
||||
|
||||
memcpy(output, hash, 32);
|
||||
}
|
||||
|
16
stratum/algos/lyra2z.h
Normal file
16
stratum/algos/lyra2z.h
Normal file
|
@ -0,0 +1,16 @@
|
|||
#ifndef LYRA2Z_H
|
||||
#define LYRA2Z_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
void lyra2z_hash(const char* input, char* output, uint32_t len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
28
stratum/algos/lyra2zz.c
Normal file
28
stratum/algos/lyra2zz.c
Normal file
|
@ -0,0 +1,28 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "Lyra2-zz.h"
|
||||
|
||||
#include <sha3/sph_blake.h>
|
||||
|
||||
#define _ALIGN(x) __attribute__ ((aligned(x)))
|
||||
|
||||
extern uint64_t lyra2z_height;
|
||||
|
||||
void lyra2zz_hash(const char* input, char* output, uint32_t len)
|
||||
{
|
||||
uint32_t _ALIGN(64) hashB[8], hash[8];
|
||||
sph_blake256_context ctx_blake;
|
||||
|
||||
sph_blake256_set_rounds(14);
|
||||
|
||||
sph_blake256_init(&ctx_blake);
|
||||
sph_blake256(&ctx_blake, input, 112);
|
||||
sph_blake256_close(&ctx_blake, hashB);
|
||||
|
||||
LYRA2ZZ(hash, 32, hashB, 32, hashB, 32, 8, 8, 8);
|
||||
|
||||
memcpy(output, hash, 32);
|
||||
}
|
16
stratum/algos/lyra2zz.h
Normal file
16
stratum/algos/lyra2zz.h
Normal file
|
@ -0,0 +1,16 @@
|
|||
#ifndef LYRA2ZZ_H
|
||||
#define LYRA2ZZ_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
void lyra2zz_hash(const char* input, char* output, uint32_t len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -8,16 +8,19 @@ CXXFLAGS = -O2 -I.. -march=native
|
|||
CFLAGS= $(CXXFLAGS) -std=gnu99
|
||||
LDFLAGS=-O2 -lgmp
|
||||
|
||||
SOURCES=lyra2re.c lyra2v2.c Lyra2.c Sponge.c blake.c scrypt.c c11.c x11.c x13.c sha256.c keccak.c \
|
||||
x14.c x15.c x17.c nist5.c fresh.c quark.c neoscrypt.c scryptn.c qubit.c skein.c groestl.c \
|
||||
xevan.c \
|
||||
skein2.c zr5.c bmw.c luffa.c pentablake.c whirlpool.c whirlpoolx.c blakecoin.c \
|
||||
blake2.c \
|
||||
yescrypt.c yescrypt-opt.c sha256_Y.c lbry.c \
|
||||
m7m.c magimath.cpp velvet.c \
|
||||
argon2a.c ar2/blake2b.c ar2/argon2.c ar2/ref.c ar2/cores.c ar2/ar2-scrypt-jane.c \
|
||||
hive.c pomelo.c \
|
||||
sib.c veltor.c gost.c x11evo.c
|
||||
SOURCES=lyra2re.c lyra2v2.c lyra2v3.c Lyra2.c lyra2z.c Lyra2-z.c lyra2zz.c Lyra2-zz.c Sponge.c allium.c \
|
||||
c11.c x11.c x12.c x13.c hsr14.c sm3.c x14.c x15.c x17.c \
|
||||
x22i.c SWIFFTX/SWIFFTX.c \
|
||||
blake.c blakecoin.c blake2b.c blake2s.c jha.c keccak.c lbry.c tribus.c exosis.c \
|
||||
deep.c fresh.c groestl.c neoscrypt.c nist5.c quark.c qubit.c skein.c skein2.c \
|
||||
bitcore.c timetravel.c x11evo.c x16r.c x16rv2.c x16s.c xevan.c bastion.c hmq17.c sonoa.c \
|
||||
bmw.c luffa.c pentablake.c vitalium.c whirlpool.c whirlpoolx.c zr5.c \
|
||||
scrypt.c scryptn.c sha256.c sha256t.c sha256q.c \
|
||||
yescrypt.c yescrypt-opt.c sha256_Y.c \
|
||||
a5a.c a5amath.c m7m.c magimath.cpp velvet.c \
|
||||
argon2a.c blake2/blake2b.c ar2/argon2.c ar2/core.c ar2/encoding.c ar2/opt.c ar2/thread.c ar2/ar2-scrypt-jane.c \
|
||||
hive.c pomelo.c hex.c argon2d-dyn.c \
|
||||
phi.c phi2.c polytimos.c rainforest.c skunk.c sib.c veltor.c gost.c aergo.c lbk3.c
|
||||
|
||||
OBJECTS=$(SOURCES:%.c=%.o) $(SOURCES:%.cpp=%.o)
|
||||
OUTPUT=libalgos.a
|
||||
|
@ -39,4 +42,5 @@ $(OUTPUT): $(OBJECTS)
|
|||
clean:
|
||||
rm -f *.o
|
||||
rm -f ar2/*.o
|
||||
|
||||
rm -f blake2/*.o
|
||||
rm -f SWIFFTX/*.o
|
||||
|
|
51
stratum/algos/phi.c
Normal file
51
stratum/algos/phi.c
Normal file
|
@ -0,0 +1,51 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <sha3/sph_skein.h>
|
||||
#include <sha3/sph_jh.h>
|
||||
#include <sha3/sph_cubehash.h>
|
||||
#include <sha3/sph_fugue.h>
|
||||
#include <sha3/sph_echo.h>
|
||||
#include "gost.h"
|
||||
|
||||
#include "common.h"
|
||||
|
||||
void phi_hash(const char* input, char* output, uint32_t len)
|
||||
{
|
||||
sph_skein512_context ctx_skein;
|
||||
sph_jh512_context ctx_jh;
|
||||
sph_cubehash512_context ctx_cubehash;
|
||||
sph_fugue512_context ctx_fugue;
|
||||
sph_gost512_context ctx_gost;
|
||||
sph_echo512_context ctx_echo;
|
||||
|
||||
uint8_t _ALIGN(128) hash[64];
|
||||
|
||||
sph_skein512_init(&ctx_skein);
|
||||
sph_skein512(&ctx_skein, input, len);
|
||||
sph_skein512_close(&ctx_skein, (void*) hash);
|
||||
|
||||
sph_jh512_init(&ctx_jh);
|
||||
sph_jh512(&ctx_jh, (const void*) hash, 64);
|
||||
sph_jh512_close(&ctx_jh, (void*) hash);
|
||||
|
||||
sph_cubehash512_init(&ctx_cubehash);
|
||||
sph_cubehash512(&ctx_cubehash, (const void*) hash, 64);
|
||||
sph_cubehash512_close(&ctx_cubehash, (void*) hash);
|
||||
|
||||
sph_fugue512_init(&ctx_fugue);
|
||||
sph_fugue512(&ctx_fugue, (const void*) hash, 64);
|
||||
sph_fugue512_close(&ctx_fugue, (void*) hash);
|
||||
|
||||
sph_gost512_init(&ctx_gost);
|
||||
sph_gost512(&ctx_gost, (const void*) hash, 64);
|
||||
sph_gost512_close(&ctx_gost, (void*) hash);
|
||||
|
||||
sph_echo512_init(&ctx_echo);
|
||||
sph_echo512(&ctx_echo, (const void*) hash, 64);
|
||||
sph_echo512_close(&ctx_echo, (void*) hash);
|
||||
|
||||
memcpy(output, hash, 32);
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue