Implement UIP1 hard fork. Replace Ethash with Ubqhash

This commit is contained in:
Julian Yap 2018-10-19 01:24:57 -07:00
parent 29de894d53
commit 46e448a027
67 changed files with 3188 additions and 698 deletions

View file

@ -25,7 +25,7 @@ import (
"strconv"
"strings"
"github.com/ethereum/ethash"
"github.com/ubiq/ubqhash"
"github.com/ubiq/go-ubiq/cmd/utils"
"github.com/ubiq/go-ubiq/eth"
"github.com/ubiq/go-ubiq/params"
@ -36,11 +36,11 @@ var (
makedagCommand = cli.Command{
Action: makedag,
Name: "makedag",
Usage: "Generate ethash DAG (for testing)",
Usage: "Generate ubqhash DAG (for testing)",
ArgsUsage: "<blockNum> <outputDir>",
Category: "MISCELLANEOUS COMMANDS",
Description: `
The makedag command generates an ethash DAG in /tmp/dag.
The makedag command generates an ubqhash DAG in /tmp/dag.
This command exists to support the system testing project.
Regular users do not need to execute it.
@ -87,7 +87,7 @@ func makedag(ctx *cli.Context) error {
utils.Fatalf("Can't find dir")
}
fmt.Println("making DAG, this could take awhile...")
ethash.MakeDAG(blockNum, dir)
ubqhash.MakeDAG(blockNum, dir)
}
default:
wrongArgs()

View file

@ -28,7 +28,7 @@ import (
"strconv"
"strings"
"github.com/ethereum/ethash"
"github.com/ubiq/ubqhash"
"github.com/ubiq/go-ubiq/accounts"
"github.com/ubiq/go-ubiq/accounts/keystore"
"github.com/ubiq/go-ubiq/common"
@ -912,7 +912,7 @@ func MakeChain(ctx *cli.Context, stack *node.Node) (chain *core.BlockChain, chai
pow := pow.PoW(core.FakePow{})
if !ctx.GlobalBool(FakePoWFlag.Name) {
pow = ethash.New()
pow = ubqhash.New()
}
chain, err = core.NewBlockChain(chainDb, chainConfig, pow, new(event.TypeMux), vm.Config{EnablePreimageRecording: ctx.GlobalBool(VMEnableDebugFlag.Name)})
if err != nil {

View file

@ -27,7 +27,7 @@ import (
"testing"
"time"
"github.com/ethereum/ethash"
"github.com/ubiq/ubqhash"
"github.com/hashicorp/golang-lru"
"github.com/ubiq/go-ubiq/common"
"github.com/ubiq/go-ubiq/core/state"
@ -46,7 +46,7 @@ func init() {
}
func thePow() pow.PoW {
pow, _ := ethash.NewForTesting()
pow, _ := ubqhash.NewForTesting()
return pow
}

View file

@ -30,7 +30,7 @@ import (
"strings"
"time"
"github.com/ethereum/ethash"
"github.com/ubiq/ubqhash"
"github.com/ubiq/go-ubiq/common"
"github.com/ubiq/go-ubiq/common/hexutil"
"github.com/ubiq/go-ubiq/core"
@ -190,7 +190,7 @@ func (s *PrivateMinerAPI) StopAutoDAG() bool {
// MakeDAG creates the new DAG for the given block number
func (s *PrivateMinerAPI) MakeDAG(blockNr rpc.BlockNumber) (bool, error) {
if err := ethash.MakeDAG(uint64(blockNr.Int64()), ""); err != nil {
if err := ubqhash.MakeDAG(uint64(blockNr.Int64()), ""); err != nil {
return false, err
}
return true, nil

View file

@ -28,7 +28,7 @@ import (
"sync"
"time"
"github.com/ethereum/ethash"
"github.com/ubiq/ubqhash"
"github.com/ubiq/go-ubiq/accounts"
"github.com/ubiq/go-ubiq/common"
"github.com/ubiq/go-ubiq/core"
@ -52,7 +52,7 @@ import (
const (
epochLength = 30000
ethashRevision = 23
ubqhashRevision = 23
autoDAGcheckInterval = 10 * time.Hour
autoDAGepochHeight = epochLength / 2
@ -286,16 +286,16 @@ func SetupGenesisBlock(chainDb *ethdb.Database, config *Config) error {
func CreatePoW(config *Config) (pow.PoW, error) {
switch {
case config.PowFake:
glog.V(logger.Info).Infof("ethash used in fake mode")
glog.V(logger.Info).Infof("ubqhash used in fake mode")
return pow.PoW(core.FakePow{}), nil
case config.PowTest:
glog.V(logger.Info).Infof("ethash used in test mode")
return ethash.NewForTesting()
glog.V(logger.Info).Infof("ubqhash used in test mode")
return ubqhash.NewForTesting()
case config.PowShared:
glog.V(logger.Info).Infof("ethash used in shared mode")
return ethash.NewShared(), nil
glog.V(logger.Info).Infof("ubqhash used in shared mode")
return ubqhash.NewShared(), nil
default:
return ethash.New(), nil
return ubqhash.New(), nil
}
}
@ -453,7 +453,7 @@ func (s *Ethereum) WaitForShutdown() {
// StartAutoDAG() spawns a go routine that checks the DAG every autoDAGcheckInterval
// by default that is 10 times per epoch
// in epoch n, if we past autoDAGepochHeight within-epoch blocks,
// it calls ethash.MakeDAG to pregenerate the DAG for the next epoch n+1
// it calls ubqhash.MakeDAG to pregenerate the DAG for the next epoch n+1
// if it does not exist yet as well as remove the DAG for epoch n-1
// the loop quits if autodagquit channel is closed, it can safely restart and
// stop any number of times.
@ -464,29 +464,29 @@ func (self *Ethereum) StartAutoDAG() {
return // already started
}
go func() {
glog.V(logger.Info).Infof("Automatic pregeneration of ethash DAG ON (ethash dir: %s)", ethash.DefaultDir)
glog.V(logger.Info).Infof("Automatic pregeneration of ubqhash DAG ON (ubqhash dir: %s)", ubqhash.DefaultDir)
var nextEpoch uint64
timer := time.After(0)
self.autodagquit = make(chan bool)
for {
select {
case <-timer:
glog.V(logger.Info).Infof("checking DAG (ethash dir: %s)", ethash.DefaultDir)
glog.V(logger.Info).Infof("checking DAG (ubqhash dir: %s)", ubqhash.DefaultDir)
currentBlock := self.BlockChain().CurrentBlock().NumberU64()
thisEpoch := currentBlock / epochLength
if nextEpoch <= thisEpoch {
if currentBlock%epochLength > autoDAGepochHeight {
if thisEpoch > 0 {
previousDag, previousDagFull := dagFiles(thisEpoch - 1)
os.Remove(filepath.Join(ethash.DefaultDir, previousDag))
os.Remove(filepath.Join(ethash.DefaultDir, previousDagFull))
os.Remove(filepath.Join(ubqhash.DefaultDir, previousDag))
os.Remove(filepath.Join(ubqhash.DefaultDir, previousDagFull))
glog.V(logger.Info).Infof("removed DAG for epoch %d (%s)", thisEpoch-1, previousDag)
}
nextEpoch = thisEpoch + 1
dag, _ := dagFiles(nextEpoch)
if _, err := os.Stat(dag); os.IsNotExist(err) {
glog.V(logger.Info).Infof("Pregenerating DAG for epoch %d (%s)", nextEpoch, dag)
err := ethash.MakeDAG(nextEpoch*epochLength, "") // "" -> ethash.DefaultDir
err := ubqhash.MakeDAG(nextEpoch*epochLength, "") // "" -> ubqhash.DefaultDir
if err != nil {
glog.V(logger.Error).Infof("Error generating DAG for epoch %d (%s)", nextEpoch, dag)
return
@ -510,13 +510,13 @@ func (self *Ethereum) StopAutoDAG() {
close(self.autodagquit)
self.autodagquit = nil
}
glog.V(logger.Info).Infof("Automatic pregeneration of ethash DAG OFF (ethash dir: %s)", ethash.DefaultDir)
glog.V(logger.Info).Infof("Automatic pregeneration of ubqhash DAG OFF (ubqhash dir: %s)", ubqhash.DefaultDir)
}
// dagFiles(epoch) returns the two alternative DAG filenames (not a path)
// 1) <revision>-<hex(seedhash[8])> 2) full-R<revision>-<hex(seedhash[8])>
func dagFiles(epoch uint64) (string, string) {
seedHash, _ := ethash.GetSeedHash(epoch * epochLength)
dag := fmt.Sprintf("full-R%d-%x", ethashRevision, seedHash[:8])
seedHash, _ := ubqhash.GetSeedHash(epoch * epochLength)
dag := fmt.Sprintf("full-R%d-%x", ubqhashRevision, seedHash[:8])
return dag, "full-R" + dag
}

View file

@ -26,7 +26,7 @@ import (
"strings"
"time"
"github.com/ethereum/ethash"
"github.com/ubiq/ubqhash"
"github.com/syndtr/goleveldb/leveldb"
"github.com/syndtr/goleveldb/leveldb/util"
"github.com/ubiq/go-ubiq/accounts"
@ -1276,7 +1276,7 @@ func (api *PublicDebugAPI) SeedHash(ctx context.Context, number uint64) (string,
if block == nil {
return "", fmt.Errorf("block #%d not found", number)
}
hash, err := ethash.GetSeedHash(number)
hash, err := ubqhash.GetSeedHash(number)
if err != nil {
return "", err
}

View file

@ -23,7 +23,7 @@ import (
"runtime"
"testing"
"github.com/ethereum/ethash"
"github.com/ubiq/ubqhash"
"github.com/ubiq/go-ubiq/common"
"github.com/ubiq/go-ubiq/core"
"github.com/ubiq/go-ubiq/core/types"
@ -83,7 +83,7 @@ func init() {
}
func thePow() pow.PoW {
pow, _ := ethash.NewForTesting()
pow, _ := ubqhash.NewForTesting()
return pow
}

View file

@ -123,7 +123,7 @@ var severityName = []string{
// matching vmodule filters.
var trimPrefixes = []string{
"/github.com/ubiq/go-ubiq",
"/github.com/ethereum/ethash",
"/github.com/ubiq/ubqhash",
}
func trimToImportPath(file string) string {

View file

@ -23,7 +23,7 @@ import (
"sync/atomic"
"time"
"github.com/ethereum/ethash"
"github.com/ubiq/ubqhash"
"github.com/ubiq/go-ubiq/common"
"github.com/ubiq/go-ubiq/core/types"
"github.com/ubiq/go-ubiq/logger"
@ -115,7 +115,7 @@ func (a *RemoteAgent) GetWork() ([3]string, error) {
block := a.currentWork.Block
res[0] = block.HashNoNonce().Hex()
seedHash, _ := ethash.GetSeedHash(block.NumberU64())
seedHash, _ := ubqhash.GetSeedHash(block.NumberU64())
res[1] = common.BytesToHash(seedHash).Hex()
// Calculate the "target" to be returned to the external miner
n := big.NewInt(1)

View file

@ -1,12 +0,0 @@
.idea/
.DS_Store
*/**/*un~
.vagrant/
*.pyc
build/
pyethash.egg-info/
*.so
*~
*.swp
MANIFEST
dist/

View file

@ -1,23 +0,0 @@
language: go
go:
- 1.4.2
before_install:
# for g++4.8 and C++11
- sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
# Set up go-ethereum
- sudo apt-get update -y -qq
- sudo apt-get install -yqq libgmp3-dev
- git clone --depth=10 https://github.com/ubiq/go-ubiq ${GOPATH}/src/github.com/ubiq/go-ubiq
# use canned dependencies from the go-ethereum repository
- export GOPATH=$GOPATH:$GOPATH/src/github.com/ubiq/go-ubiq/Godeps/_workspace/
- echo $GOPATH
install:
# need to explicitly request version 1.48 since by default we get 1.46 which does not work with C++11
- sudo apt-get install -qq --yes --force-yes g++-4.8
- sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.8 50
- sudo apt-get install -qq wget cmake bash libboost-test1.48-dev libboost-system1.48-dev libboost-filesystem1.48-dev nodejs python-pip python-dev valgrind
- sudo pip install virtualenv -q
script: "./test/test.sh"

View file

@ -1,14 +0,0 @@
cmake_minimum_required(VERSION 2.8.7)
project(ethash)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/modules/")
set(ETHHASH_LIBS ethash)
if (WIN32 AND WANT_CRYPTOPP)
add_subdirectory(cryptopp)
endif()
add_subdirectory(src/libethash)
add_subdirectory(src/benchmark EXCLUDE_FROM_ALL)
add_subdirectory(test/c)

View file

@ -1,17 +0,0 @@
include setup.py
# C sources
include src/libethash/internal.c
include src/libethash/sha3.c
include src/libethash/util.c
include src/python/core.c
# Headers
include src/libethash/compiler.h
include src/libethash/data_sizes.h
include src/libethash/endian.h
include src/libethash/ethash.h
include src/libethash/fnv.h
include src/libethash/internal.h
include src/libethash/sha3.h
include src/libethash/util.h

View file

@ -1,6 +0,0 @@
.PHONY: clean test
test:
./test/test.sh
clean:
rm -rf *.so pyethash.egg-info/ build/ test/python/python-virtual-env/ test/c/build/ pyethash.so test/python/*.pyc dist/ MANIFEST

View file

@ -1,22 +0,0 @@
[![Build Status](https://travis-ci.org/ethereum/ethash.svg?branch=master)](https://travis-ci.org/ethereum/ethash)
[![Windows Build Status](https://ci.appveyor.com/api/projects/status/github/debris/ethash?branch=master&svg=true)](https://ci.appveyor.com/project/debris/ethash-nr37r/branch/master)
# Ethash
For details on this project, please see the Ethereum wiki:
https://github.com/ubiq/wiki/wiki/Ethash
### Coding Style for C++ code:
Follow the same exact style as in [cpp-ethereum](https://github.com/ethereum/cpp-ethereum/blob/develop/CodingStandards.txt)
### Coding Style for C code:
The main thing above all is code consistency.
- Tabs for indentation. A tab is 4 spaces
- Try to stick to the [K&R](http://en.wikipedia.org/wiki/Indent_style#K.26R_style),
especially for the C code.
- Keep the line lengths reasonable. No hard limit on 80 characters but don't go further
than 110. Some people work with multiple buffers next to each other.
Make them like you :)

View file

@ -1,43 +0,0 @@
version: 1.0.0.{build}
environment:
BOOST_ROOT: "c:/projects/ethash/deps/boost"
branches:
only:
- master
- develop
os: Windows Server 2012 R2
clone_folder: c:\projects\ethash
#platform: Any CPU
#configuration: Debug
install:
# by default, all script lines are interpreted as batch
# scripts to run before build
before_build:
- echo "Downloading boost..."
- mkdir c:\projects\ethash\deps
- cd c:\projects\ethash\deps
- curl -O https://build.ethdev.com/builds/windows-precompiled/boost.tar.gz
- echo "Unzipping boost..."
- 7z x boost.tar.gz > nul
- 7z x boost.tar > nul
- ls
- echo "Running cmake..."
- cd c:\projects\ethash
- cmake .
build:
project: ALL_BUILD.vcxproj # path to Visual Studio solution or project
after_build:
- echo "Running tests..."
- cd c:\projects\ethash\test\c\Debug
- Test.exe
- echo "Finished!"

View file

@ -1,47 +0,0 @@
#!/usr/bin/env python
import os
from distutils.core import setup, Extension
sources = [
'src/python/core.c',
'src/libethash/io.c',
'src/libethash/internal.c',
'src/libethash/sha3.c']
if os.name == 'nt':
sources += [
'src/libethash/util_win32.c',
'src/libethash/io_win32.c',
'src/libethash/mmap_win32.c',
]
else:
sources += [
'src/libethash/io_posix.c'
]
depends = [
'src/libethash/ethash.h',
'src/libethash/compiler.h',
'src/libethash/data_sizes.h',
'src/libethash/endian.h',
'src/libethash/ethash.h',
'src/libethash/io.h',
'src/libethash/fnv.h',
'src/libethash/internal.h',
'src/libethash/sha3.h',
'src/libethash/util.h',
]
pyethash = Extension('pyethash',
sources=sources,
depends=depends,
extra_compile_args=["-Isrc/", "-std=gnu99", "-Wall"])
setup(
name='pyethash',
author="Matthew Wampler-Doty",
author_email="matthew.wampler.doty@gmail.com",
license='GPL',
version='0.1.23',
url='https://github.com/ethereum/ethash',
download_url='https://github.com/ethereum/ethash/tarball/v23',
description=('Python wrappers for ethash, the ethereum proof of work'
'hashing function'),
ext_modules=[pyethash],
)

View file

@ -1,119 +0,0 @@
/*
This file is part of ethash.
ethash is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ethash is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with ethash. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file io.c
* @author Lefteris Karapetsas <lefteris@ethdev.com>
* @date 2015
*/
#include "io.h"
#include <string.h>
#include <stdio.h>
#include <errno.h>
enum ethash_io_rc ethash_io_prepare(
char const* dirname,
ethash_h256_t const seedhash,
FILE** output_file,
uint64_t file_size,
bool force_create
)
{
char mutable_name[DAG_MUTABLE_NAME_MAX_SIZE];
enum ethash_io_rc ret = ETHASH_IO_FAIL;
// reset errno before io calls
errno = 0;
// assert directory exists
if (!ethash_mkdir(dirname)) {
ETHASH_CRITICAL("Could not create the ethash directory");
goto end;
}
ethash_io_mutable_name(ETHASH_REVISION, &seedhash, mutable_name);
char* tmpfile = ethash_io_create_filename(dirname, mutable_name, strlen(mutable_name));
if (!tmpfile) {
ETHASH_CRITICAL("Could not create the full DAG pathname");
goto end;
}
FILE *f;
if (!force_create) {
// try to open the file
f = ethash_fopen(tmpfile, "rb+");
if (f) {
size_t found_size;
if (!ethash_file_size(f, &found_size)) {
fclose(f);
ETHASH_CRITICAL("Could not query size of DAG file: \"%s\"", tmpfile);
goto free_memo;
}
if (file_size != found_size - ETHASH_DAG_MAGIC_NUM_SIZE) {
fclose(f);
ret = ETHASH_IO_MEMO_SIZE_MISMATCH;
goto free_memo;
}
// compare the magic number, no need to care about endianess since it's local
uint64_t magic_num;
if (fread(&magic_num, ETHASH_DAG_MAGIC_NUM_SIZE, 1, f) != 1) {
// I/O error
fclose(f);
ETHASH_CRITICAL("Could not read from DAG file: \"%s\"", tmpfile);
ret = ETHASH_IO_MEMO_SIZE_MISMATCH;
goto free_memo;
}
if (magic_num != ETHASH_DAG_MAGIC_NUM) {
fclose(f);
ret = ETHASH_IO_MEMO_SIZE_MISMATCH;
goto free_memo;
}
ret = ETHASH_IO_MEMO_MATCH;
goto set_file;
}
}
// file does not exist, will need to be created
f = ethash_fopen(tmpfile, "wb+");
if (!f) {
ETHASH_CRITICAL("Could not create DAG file: \"%s\"", tmpfile);
goto free_memo;
}
// make sure it's of the proper size
if (fseek(f, (long int)(file_size + ETHASH_DAG_MAGIC_NUM_SIZE - 1), SEEK_SET) != 0) {
fclose(f);
ETHASH_CRITICAL("Could not seek to the end of DAG file: \"%s\". Insufficient space?", tmpfile);
goto free_memo;
}
if (fputc('\n', f) == EOF) {
fclose(f);
ETHASH_CRITICAL("Could not write in the end of DAG file: \"%s\". Insufficient space?", tmpfile);
goto free_memo;
}
if (fflush(f) != 0) {
fclose(f);
ETHASH_CRITICAL("Could not flush at end of DAG file: \"%s\". Insufficient space?", tmpfile);
goto free_memo;
}
ret = ETHASH_IO_MEMO_MISMATCH;
goto set_file;
ret = ETHASH_IO_MEMO_MATCH;
set_file:
*output_file = f;
free_memo:
free(tmpfile);
end:
return ret;
}

31
vendor/github.com/ubiq/ubqhash/compat.go generated vendored Normal file
View file

@ -0,0 +1,31 @@
// Copyright 2017 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package ubqhash
import (
"math/big"
"github.com/ubiq/go-ubiq/common"
)
type Block interface {
Difficulty() *big.Int
HashNoNonce() common.Hash
Nonce() uint64
MixDigest() common.Hash
NumberU64() uint64
}

View file

@ -1,4 +1,4 @@
set(LIBRARY ethash)
set(LIBRARY ubqhash)
if (CPPETHEREUM)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
@ -13,7 +13,7 @@ endif()
set(FILES util.h
io.c
internal.c
ethash.h
ubqhash.h
endian.h
compiler.h
fnv.h
@ -26,15 +26,15 @@ else()
endif()
if (NOT CRYPTOPP_FOUND)
find_package(CryptoPP 5.6.2)
find_package(CryptoPP 7.0.0)
endif()
if (CRYPTOPP_FOUND)
add_definitions(-DWITH_CRYPTOPP)
include_directories( ${CRYPTOPP_INCLUDE_DIRS} )
list(APPEND FILES sha3_cryptopp.cpp sha3_cryptopp.h)
list(APPEND FILES sha3_cryptopp.cpp sha3_cryptopp.h blake2_cryptopp.cpp blake2_cryptopp.h)
else()
list(APPEND FILES sha3.c sha3.h)
list(APPEND FILES sha3.c sha3.h blake2b-ref.c blake2-impl.h blake2.h)
endif()
add_library(${LIBRARY} ${FILES})

View file

@ -0,0 +1,160 @@
/*
BLAKE2 reference source code package - reference C implementations
Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the
terms of the CC0, the OpenSSL Licence, 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
- OpenSSL license : https://www.openssl.org/source/license.html
- Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
More information about the BLAKE2 hash function can be found at
https://blake2.net.
*/
#ifndef BLAKE2_IMPL_H
#define BLAKE2_IMPL_H
#include <stdint.h>
#include <string.h>
#if !defined(__cplusplus) && (!defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L)
#if defined(_MSC_VER)
#define BLAKE2_INLINE __inline
#elif defined(__GNUC__)
#define BLAKE2_INLINE __inline__
#else
#define BLAKE2_INLINE
#endif
#else
#define BLAKE2_INLINE inline
#endif
static BLAKE2_INLINE uint32_t load32( const void *src )
{
#if defined(NATIVE_LITTLE_ENDIAN)
uint32_t w;
memcpy(&w, src, sizeof w);
return w;
#else
const uint8_t *p = ( const uint8_t * )src;
return (( uint32_t )( p[0] ) << 0) |
(( uint32_t )( p[1] ) << 8) |
(( uint32_t )( p[2] ) << 16) |
(( uint32_t )( p[3] ) << 24) ;
#endif
}
static BLAKE2_INLINE uint64_t load64( const void *src )
{
#if defined(NATIVE_LITTLE_ENDIAN)
uint64_t w;
memcpy(&w, src, sizeof w);
return w;
#else
const uint8_t *p = ( const uint8_t * )src;
return (( uint64_t )( p[0] ) << 0) |
(( uint64_t )( p[1] ) << 8) |
(( uint64_t )( p[2] ) << 16) |
(( uint64_t )( p[3] ) << 24) |
(( uint64_t )( p[4] ) << 32) |
(( uint64_t )( p[5] ) << 40) |
(( uint64_t )( p[6] ) << 48) |
(( uint64_t )( p[7] ) << 56) ;
#endif
}
static BLAKE2_INLINE uint16_t load16( const void *src )
{
#if defined(NATIVE_LITTLE_ENDIAN)
uint16_t w;
memcpy(&w, src, sizeof w);
return w;
#else
const uint8_t *p = ( const uint8_t * )src;
return (( uint16_t )( p[0] ) << 0) |
(( uint16_t )( p[1] ) << 8) ;
#endif
}
static BLAKE2_INLINE void store16( void *dst, uint16_t w )
{
#if defined(NATIVE_LITTLE_ENDIAN)
memcpy(dst, &w, sizeof w);
#else
uint8_t *p = ( uint8_t * )dst;
*p++ = ( uint8_t )w; w >>= 8;
*p++ = ( uint8_t )w;
#endif
}
static BLAKE2_INLINE void store32( void *dst, uint32_t w )
{
#if defined(NATIVE_LITTLE_ENDIAN)
memcpy(dst, &w, sizeof w);
#else
uint8_t *p = ( uint8_t * )dst;
p[0] = (uint8_t)(w >> 0);
p[1] = (uint8_t)(w >> 8);
p[2] = (uint8_t)(w >> 16);
p[3] = (uint8_t)(w >> 24);
#endif
}
static BLAKE2_INLINE void store64( void *dst, uint64_t w )
{
#if defined(NATIVE_LITTLE_ENDIAN)
memcpy(dst, &w, sizeof w);
#else
uint8_t *p = ( uint8_t * )dst;
p[0] = (uint8_t)(w >> 0);
p[1] = (uint8_t)(w >> 8);
p[2] = (uint8_t)(w >> 16);
p[3] = (uint8_t)(w >> 24);
p[4] = (uint8_t)(w >> 32);
p[5] = (uint8_t)(w >> 40);
p[6] = (uint8_t)(w >> 48);
p[7] = (uint8_t)(w >> 56);
#endif
}
static BLAKE2_INLINE uint64_t load48( const void *src )
{
const uint8_t *p = ( const uint8_t * )src;
return (( uint64_t )( p[0] ) << 0) |
(( uint64_t )( p[1] ) << 8) |
(( uint64_t )( p[2] ) << 16) |
(( uint64_t )( p[3] ) << 24) |
(( uint64_t )( p[4] ) << 32) |
(( uint64_t )( p[5] ) << 40) ;
}
static BLAKE2_INLINE void store48( void *dst, uint64_t w )
{
uint8_t *p = ( uint8_t * )dst;
p[0] = (uint8_t)(w >> 0);
p[1] = (uint8_t)(w >> 8);
p[2] = (uint8_t)(w >> 16);
p[3] = (uint8_t)(w >> 24);
p[4] = (uint8_t)(w >> 32);
p[5] = (uint8_t)(w >> 40);
}
static BLAKE2_INLINE uint32_t rotr32( const uint32_t w, const unsigned c )
{
return ( w >> c ) | ( w << ( 32 - c ) );
}
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 secure_zero_memory(void *v, size_t n)
{
static void *(*const volatile memset_v)(void *, int, size_t) = &memset;
memset_v(v, 0, n);
}
#endif

168
vendor/github.com/ubiq/ubqhash/src/libubqhash/blake2.h generated vendored Normal file
View file

@ -0,0 +1,168 @@
/*
BLAKE2 reference source code package - reference C implementations
Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the
terms of the CC0, the OpenSSL Licence, 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
- OpenSSL license : https://www.openssl.org/source/license.html
- Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
More information about the BLAKE2 hash function can be found at
https://blake2.net.
*/
#ifndef BLAKE2_H
#define BLAKE2_H
#include <stddef.h>
#include <stdint.h>
#if defined(_MSC_VER)
#define BLAKE2_PACKED(x) __pragma(pack(push, 1)) x __pragma(pack(pop))
#else
#define BLAKE2_PACKED(x) x __attribute__((packed))
#endif
#if defined(__cplusplus)
extern "C" {
#endif
struct ubqhash_h256;
enum blake2s_constant
{
BLAKE2S_BLOCKBYTES = 64,
BLAKE2S_OUTBYTES = 32,
BLAKE2S_KEYBYTES = 32,
BLAKE2S_SALTBYTES = 8,
BLAKE2S_PERSONALBYTES = 8
};
enum blake2b_constant
{
BLAKE2B_BLOCKBYTES = 128,
BLAKE2B_OUTBYTES = 64,
BLAKE2B_KEYBYTES = 64,
BLAKE2B_SALTBYTES = 16,
BLAKE2B_PERSONALBYTES = 16
};
typedef struct blake2s_state__
{
uint32_t h[8];
uint32_t t[2];
uint32_t f[2];
uint8_t buf[BLAKE2S_BLOCKBYTES];
size_t buflen;
size_t outlen;
uint8_t last_node;
} blake2s_state;
typedef struct blake2b_state__
{
uint64_t h[8];
uint64_t t[2];
uint64_t f[2];
uint8_t buf[BLAKE2B_BLOCKBYTES];
size_t buflen;
size_t outlen;
uint8_t last_node;
} blake2b_state;
typedef struct blake2sp_state__
{
blake2s_state S[8][1];
blake2s_state R[1];
uint8_t buf[8 * BLAKE2S_BLOCKBYTES];
size_t buflen;
size_t outlen;
} blake2sp_state;
typedef struct blake2bp_state__
{
blake2b_state S[4][1];
blake2b_state R[1];
uint8_t buf[4 * BLAKE2B_BLOCKBYTES];
size_t buflen;
size_t outlen;
} blake2bp_state;
BLAKE2_PACKED(struct blake2s_param__
{
uint8_t digest_length; /* 1 */
uint8_t key_length; /* 2 */
uint8_t fanout; /* 3 */
uint8_t depth; /* 4 */
uint32_t leaf_length; /* 8 */
uint32_t node_offset; /* 12 */
uint16_t xof_length; /* 14 */
uint8_t node_depth; /* 15 */
uint8_t inner_length; /* 16 */
/* uint8_t reserved[0]; */
uint8_t salt[BLAKE2S_SALTBYTES]; /* 24 */
uint8_t personal[BLAKE2S_PERSONALBYTES]; /* 32 */
});
typedef struct blake2s_param__ blake2s_param;
BLAKE2_PACKED(struct blake2b_param__
{
uint8_t digest_length; /* 1 */
uint8_t key_length; /* 2 */
uint8_t fanout; /* 3 */
uint8_t depth; /* 4 */
uint32_t leaf_length; /* 8 */
uint32_t node_offset; /* 12 */
uint32_t xof_length; /* 16 */
uint8_t node_depth; /* 17 */
uint8_t inner_length; /* 18 */
uint8_t reserved[14]; /* 32 */
uint8_t salt[BLAKE2B_SALTBYTES]; /* 48 */
uint8_t personal[BLAKE2B_PERSONALBYTES]; /* 64 */
});
typedef struct blake2b_param__ blake2b_param;
typedef struct blake2xs_state__
{
blake2s_state S[1];
blake2s_param P[1];
} blake2xs_state;
typedef struct blake2xb_state__
{
blake2b_state S[1];
blake2b_param P[1];
} blake2xb_state;
/* Padded structs result in a compile-time error */
enum {
BLAKE2_DUMMY_1 = 1/(sizeof(blake2s_param) == BLAKE2S_OUTBYTES),
BLAKE2_DUMMY_2 = 1/(sizeof(blake2b_param) == BLAKE2B_OUTBYTES)
};
/* Streaming API */
int blake2b_init( blake2b_state *S, size_t outlen );
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 );
int blake2b_final( blake2b_state *S, void *out, size_t outlen );
/* Simple API */
int blake2b( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen );
/* This is simply an alias for blake2b */
int blake2( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen );
static inline void BLAKE2B_512(uint8_t* ret, uint8_t const* data, size_t const size)
{
blake2b(ret, 64, data, size, 0, 0 );
}
#if defined(__cplusplus)
}
#endif
#endif

View file

@ -0,0 +1,32 @@
/*
This file is part of ubqhash.
ubqhash is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ubqhash is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with ubqhash. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file sha3.cpp
* @author Tim Hughes <tim@twistedfury.com>
* @date 2015
*/
#include <stdint.h>
#include <cryptopp/blake2.h>
extern "C" {
struct ubqhash_h256;
typedef struct ubqhash_h256 ubqhash_h256_t;
void BLAKE2B_512(uint8_t* const ret, uint8_t const* data, size_t size)
{
CryptoPP::BLAKE2b().CalculateDigest(ret, data, size);
}
}

View file

@ -0,0 +1,17 @@
#pragma once
#include "compiler.h"
#include <stdint.h>
#include <stdlib.h>
#ifdef __cplusplus
extern "C" {
#endif
struct ubqhash_h256;
void BLAKE2B_512(uint8_t* const ret, uint8_t const* data, size_t size);
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,379 @@
/*
BLAKE2 reference source code package - reference C implementations
Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the
terms of the CC0, the OpenSSL Licence, 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
- OpenSSL license : https://www.openssl.org/source/license.html
- Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
More information about the BLAKE2 hash function can be found at
https://blake2.net.
*/
#include <stdint.h>
#include <string.h>
#include <stdio.h>
#include "blake2.h"
#include "blake2-impl.h"
static const uint64_t blake2b_IV[8] =
{
0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL,
0x3c6ef372fe94f82bULL, 0xa54ff53a5f1d36f1ULL,
0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL,
0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL
};
static const uint8_t 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 void blake2b_set_lastnode( blake2b_state *S )
{
S->f[1] = (uint64_t)-1;
}
/* Some helper functions, not necessarily useful */
static int blake2b_is_lastblock( const blake2b_state *S )
{
return S->f[0] != 0;
}
static void blake2b_set_lastblock( blake2b_state *S )
{
if( S->last_node ) blake2b_set_lastnode( S );
S->f[0] = (uint64_t)-1;
}
static void blake2b_increment_counter( blake2b_state *S, const uint64_t inc )
{
S->t[0] += inc;
S->t[1] += ( S->t[0] < inc );
}
static void blake2b_init0( blake2b_state *S )
{
size_t i;
memset( S, 0, sizeof( blake2b_state ) );
for( i = 0; i < 8; ++i ) S->h[i] = blake2b_IV[i];
}
/* init xors IV with input parameter block */
int blake2b_init_param( blake2b_state *S, const blake2b_param *P )
{
const uint8_t *p = ( const uint8_t * )( P );
size_t i;
blake2b_init0( S );
/* IV XOR ParamBlock */
for( i = 0; i < 8; ++i )
S->h[i] ^= load64( p + sizeof( S->h[i] ) * i );
S->outlen = P->digest_length;
return 0;
}
int blake2b_init( blake2b_state *S, size_t outlen )
{
blake2b_param P[1];
if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1;
P->digest_length = (uint8_t)outlen;
P->key_length = 0;
P->fanout = 1;
P->depth = 1;
store32( &P->leaf_length, 0 );
store32( &P->node_offset, 0 );
store32( &P->xof_length, 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[1];
if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1;
if ( !key || !keylen || keylen > BLAKE2B_KEYBYTES ) return -1;
P->digest_length = (uint8_t)outlen;
P->key_length = (uint8_t)keylen;
P->fanout = 1;
P->depth = 1;
store32( &P->leaf_length, 0 );
store32( &P->node_offset, 0 );
store32( &P->xof_length, 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 ) return -1;
{
uint8_t block[BLAKE2B_BLOCKBYTES];
memset( block, 0, BLAKE2B_BLOCKBYTES );
memcpy( block, key, keylen );
blake2b_update( S, block, BLAKE2B_BLOCKBYTES );
secure_zero_memory( block, BLAKE2B_BLOCKBYTES ); /* Burn the key from stack */
}
return 0;
}
#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(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(0)
static void blake2b_compress( blake2b_state *S, const uint8_t block[BLAKE2B_BLOCKBYTES] )
{
uint64_t m[16];
uint64_t v[16];
size_t i;
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];
ROUND( 0 );
ROUND( 1 );
ROUND( 2 );
ROUND( 3 );
ROUND( 4 );
ROUND( 5 );
ROUND( 6 );
ROUND( 7 );
ROUND( 8 );
ROUND( 9 );
ROUND( 10 );
ROUND( 11 );
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 *pin, size_t inlen )
{
const unsigned char * in = (const unsigned char *)pin;
if( inlen > 0 )
{
size_t left = S->buflen;
size_t fill = BLAKE2B_BLOCKBYTES - left;
if( inlen > fill )
{
S->buflen = 0;
memcpy( S->buf + left, in, fill ); /* Fill buffer */
blake2b_increment_counter( S, BLAKE2B_BLOCKBYTES );
blake2b_compress( S, S->buf ); /* Compress */
in += fill; inlen -= fill;
while(inlen > BLAKE2B_BLOCKBYTES) {
blake2b_increment_counter(S, BLAKE2B_BLOCKBYTES);
blake2b_compress( S, in );
in += BLAKE2B_BLOCKBYTES;
inlen -= BLAKE2B_BLOCKBYTES;
}
}
memcpy( S->buf + S->buflen, in, inlen );
S->buflen += inlen;
}
return 0;
}
int blake2b_final( blake2b_state *S, void *out, size_t outlen )
{
uint8_t buffer[BLAKE2B_OUTBYTES] = {0};
size_t i;
if( out == NULL || outlen < S->outlen )
return -1;
if( blake2b_is_lastblock( S ) )
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 );
secure_zero_memory(buffer, sizeof(buffer));
return 0;
}
/* inlen, at least, should be uint64_t. Others can be size_t. */
int blake2b( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen )
{
blake2b_state S[1];
/* Verify parameters */
if ( NULL == in && inlen > 0 ) return -1;
if ( NULL == out ) return -1;
if( NULL == key && keylen > 0 ) return -1;
if( !outlen || outlen > BLAKE2B_OUTBYTES ) return -1;
if( keylen > BLAKE2B_KEYBYTES ) return -1;
if( keylen > 0 )
{
if( blake2b_init_key( S, outlen, key, keylen ) < 0 ) return -1;
}
else
{
if( blake2b_init( S, outlen ) < 0 ) return -1;
}
blake2b_update( S, ( const uint8_t * )in, inlen );
blake2b_final( S, out, outlen );
return 0;
}
int blake2( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ) {
return blake2b(out, outlen, in, inlen, key, keylen);
}
#if defined(SUPERCOP)
int crypto_hash( unsigned char *out, unsigned char *in, unsigned long long inlen )
{
return blake2b( out, BLAKE2B_OUTBYTES, in, inlen, NULL, 0 );
}
#endif
#if defined(BLAKE2B_SELFTEST)
#include <string.h>
#include "blake2-kat.h"
int main( void )
{
uint8_t key[BLAKE2B_KEYBYTES];
uint8_t buf[BLAKE2_KAT_LENGTH];
size_t i, step;
for( i = 0; i < BLAKE2B_KEYBYTES; ++i )
key[i] = ( uint8_t )i;
for( i = 0; i < BLAKE2_KAT_LENGTH; ++i )
buf[i] = ( uint8_t )i;
/* Test simple API */
for( i = 0; i < BLAKE2_KAT_LENGTH; ++i )
{
uint8_t hash[BLAKE2B_OUTBYTES];
blake2b( hash, BLAKE2B_OUTBYTES, buf, i, key, BLAKE2B_KEYBYTES );
if( 0 != memcmp( hash, blake2b_keyed_kat[i], BLAKE2B_OUTBYTES ) )
{
goto fail;
}
}
/* Test streaming API */
for(step = 1; step < BLAKE2B_BLOCKBYTES; ++step) {
for (i = 0; i < BLAKE2_KAT_LENGTH; ++i) {
uint8_t hash[BLAKE2B_OUTBYTES];
blake2b_state S;
uint8_t * p = buf;
size_t mlen = i;
int err = 0;
if( (err = blake2b_init_key(&S, BLAKE2B_OUTBYTES, key, BLAKE2B_KEYBYTES)) < 0 ) {
goto fail;
}
while (mlen >= step) {
if ( (err = blake2b_update(&S, p, step)) < 0 ) {
goto fail;
}
mlen -= step;
p += step;
}
if ( (err = blake2b_update(&S, p, mlen)) < 0) {
goto fail;
}
if ( (err = blake2b_final(&S, hash, BLAKE2B_OUTBYTES)) < 0) {
goto fail;
}
if (0 != memcmp(hash, blake2b_keyed_kat[i], BLAKE2B_OUTBYTES)) {
goto fail;
}
}
}
puts( "ok" );
return 0;
fail:
puts("error");
return -1;
}
#endif

View file

@ -26,23 +26,23 @@
#if defined(_WIN32)
#include <stdlib.h>
#define ethash_swap_u32(input_) _byteswap_ulong(input_)
#define ethash_swap_u64(input_) _byteswap_uint64(input_)
#define ubqhash_swap_u32(input_) _byteswap_ulong(input_)
#define ubqhash_swap_u64(input_) _byteswap_uint64(input_)
#elif defined(__APPLE__)
#include <libkern/OSByteOrder.h>
#define ethash_swap_u32(input_) OSSwapInt32(input_)
#define ethash_swap_u64(input_) OSSwapInt64(input_)
#define ubqhash_swap_u32(input_) OSSwapInt32(input_)
#define ubqhash_swap_u64(input_) OSSwapInt64(input_)
#elif defined(__FreeBSD__) || defined(__DragonFly__) || defined(__NetBSD__)
#define ethash_swap_u32(input_) bswap32(input_)
#define ethash_swap_u64(input_) bswap64(input_)
#define ubqhash_swap_u32(input_) bswap32(input_)
#define ubqhash_swap_u64(input_) bswap64(input_)
#elif defined(__OpenBSD__)
#include <endian.h>
#define ethash_swap_u32(input_) swap32(input_)
#define ethash_swap_u64(input_) swap64(input_)
#define ubqhash_swap_u32(input_) swap32(input_)
#define ubqhash_swap_u64(input_) swap64(input_)
#else // posix
#include <byteswap.h>
#define ethash_swap_u32(input_) bswap_32(input_)
#define ethash_swap_u64(input_) bswap_64(input_)
#define ubqhash_swap_u32(input_) bswap_32(input_)
#define ubqhash_swap_u64(input_) bswap_64(input_)
#endif
@ -57,20 +57,20 @@
#elif BIG_ENDIAN == BYTE_ORDER
#define fix_endian32(dst_, src_) dst_ = ethash_swap_u32(src_)
#define fix_endian32_same(val_) val_ = ethash_swap_u32(val_)
#define fix_endian64(dst_, src_) dst_ = ethash_swap_u64(src_)
#define fix_endian64_same(val_) val_ = ethash_swap_u64(val_)
#define fix_endian32(dst_, src_) dst_ = ubqhash_swap_u32(src_)
#define fix_endian32_same(val_) val_ = ubqhash_swap_u32(val_)
#define fix_endian64(dst_, src_) dst_ = ubqhash_swap_u64(src_)
#define fix_endian64_same(val_) val_ = ubqhash_swap_u64(val_)
#define fix_endian_arr32(arr_, size_) \
do { \
for (unsigned i_ = 0; i_ < (size_); ++i_) { \
arr_[i_] = ethash_swap_u32(arr_[i_]); \
arr_[i_] = ubqhash_swap_u32(arr_[i_]); \
} \
} while (0)
#define fix_endian_arr64(arr_, size_) \
do { \
for (unsigned i_ = 0; i_ < (size_); ++i_) { \
arr_[i_] = ethash_swap_u64(arr_[i_]); \
arr_[i_] = ubqhash_swap_u64(arr_[i_]); \
} \
} while (0)
#else

View file

@ -1,12 +1,12 @@
/*
This file is part of ethash.
This file is part of ubqhash.
ethash is free software: you can redistribute it and/or modify
ubqhash is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ethash is distributed in the hope that it will be useful,
ubqhash is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
@ -26,7 +26,7 @@
#include <errno.h>
#include <math.h>
#include "mmap.h"
#include "ethash.h"
#include "ubqhash.h"
#include "fnv.h"
#include "endian.h"
#include "internal.h"
@ -36,30 +36,32 @@
#ifdef WITH_CRYPTOPP
#include "sha3_cryptopp.h"
#include "blake2_cryptopp.h"
#else
#include "sha3.h"
#include "blake2.h"
#endif // WITH_CRYPTOPP
uint64_t ethash_get_datasize(uint64_t const block_number)
uint64_t ubqhash_get_datasize(uint64_t const block_number)
{
assert(block_number / ETHASH_EPOCH_LENGTH < 2048);
return dag_sizes[block_number / ETHASH_EPOCH_LENGTH];
assert(block_number / UBQHASH_EPOCH_LENGTH < 2048);
return dag_sizes[block_number / UBQHASH_EPOCH_LENGTH];
}
uint64_t ethash_get_cachesize(uint64_t const block_number)
uint64_t ubqhash_get_cachesize(uint64_t const block_number)
{
assert(block_number / ETHASH_EPOCH_LENGTH < 2048);
return cache_sizes[block_number / ETHASH_EPOCH_LENGTH];
assert(block_number / UBQHASH_EPOCH_LENGTH < 2048);
return cache_sizes[block_number / UBQHASH_EPOCH_LENGTH];
}
// Follows Sergio's "STRICT MEMORY HARD HASHING FUNCTIONS" (2014)
// https://bitslog.files.wordpress.com/2013/12/memohash-v0-3.pdf
// SeqMemoHash(s, R, N)
bool static ethash_compute_cache_nodes(
bool static ubqhash_compute_cache_nodes(
node* const nodes,
uint64_t cache_size,
ethash_h256_t const* seed
ubqhash_h256_t const* seed
)
{
if (cache_size % sizeof(node) != 0) {
@ -73,7 +75,7 @@ bool static ethash_compute_cache_nodes(
SHA3_512(nodes[i].bytes, nodes[i - 1].bytes, 64);
}
for (uint32_t j = 0; j != ETHASH_CACHE_ROUNDS; j++) {
for (uint32_t j = 0; j != UBQHASH_CACHE_ROUNDS; j++) {
for (uint32_t i = 0; i != num_nodes; i++) {
uint32_t const idx = nodes[i].words[0] % num_nodes;
node data;
@ -90,10 +92,44 @@ bool static ethash_compute_cache_nodes(
return true;
}
void ethash_calculate_dag_item(
bool static ubqhash_compute_cache_nodes_uip1(
node* const nodes,
uint64_t cache_size,
ubqhash_h256_t const* seed
)
{
if (cache_size % sizeof(node) != 0) {
return false;
}
uint32_t const num_nodes = (uint32_t) (cache_size / sizeof(node));
BLAKE2B_512(nodes[0].bytes, (uint8_t*)seed, 32);
for (uint32_t i = 1; i != num_nodes; ++i) {
BLAKE2B_512(nodes[i].bytes, nodes[i - 1].bytes, 64);
}
for (uint32_t j = 0; j != UBQHASH_CACHE_ROUNDS; j++) {
for (uint32_t i = 0; i != num_nodes; i++) {
uint32_t const idx = nodes[i].words[0] % num_nodes;
node data;
data = nodes[(num_nodes - 1 + i) % num_nodes];
for (uint32_t w = 0; w != NODE_WORDS; ++w) {
data.words[w] ^= nodes[idx].words[w];
}
BLAKE2B_512(nodes[i].bytes, data.bytes, sizeof(data));
}
}
// now perform endian conversion
fix_endian_arr32(nodes->words, num_nodes * NODE_WORDS);
return true;
}
void ubqhash_calculate_dag_item(
node* const ret,
uint32_t node_index,
ethash_light_t const light
ubqhash_light_t const light
)
{
uint32_t num_parent_nodes = (uint32_t) (light->cache_size / sizeof(node));
@ -110,7 +146,7 @@ void ethash_calculate_dag_item(
__m128i xmm3 = ret->xmm[3];
#endif
for (uint32_t i = 0; i != ETHASH_DATASET_PARENTS; ++i) {
for (uint32_t i = 0; i != UBQHASH_DATASET_PARENTS; ++i) {
uint32_t parent_index = fnv_hash(node_index ^ i, ret->words[i % NODE_WORDS]) % num_parent_nodes;
node const *parent = &cache_nodes[parent_index];
@ -142,11 +178,11 @@ void ethash_calculate_dag_item(
SHA3_512(ret->bytes, ret->bytes, sizeof(node));
}
bool ethash_compute_full_data(
bool ubqhash_compute_full_data(
void* mem,
uint64_t full_size,
ethash_light_t const light,
ethash_callback_t callback
ubqhash_light_t const light,
ubqhash_callback_t callback
)
{
if (full_size % (sizeof(uint32_t) * MIX_WORDS) != 0 ||
@ -166,17 +202,17 @@ bool ethash_compute_full_data(
return false;
}
progress += progress_change;
ethash_calculate_dag_item(&(full_nodes[n]), n, light);
ubqhash_calculate_dag_item(&(full_nodes[n]), n, light);
}
return true;
}
static bool ethash_hash(
ethash_return_value_t* ret,
static bool ubqhash_hash(
ubqhash_return_value_t* ret,
node const* full_nodes,
ethash_light_t const light,
ubqhash_light_t const light,
uint64_t full_size,
ethash_h256_t const header_hash,
ubqhash_h256_t const header_hash,
uint64_t const nonce
)
{
@ -202,7 +238,7 @@ static bool ethash_hash(
unsigned const page_size = sizeof(uint32_t) * MIX_WORDS;
unsigned const num_full_pages = (unsigned) (full_size / page_size);
for (unsigned i = 0; i != ETHASH_ACCESSES; ++i) {
for (unsigned i = 0; i != UBQHASH_ACCESSES; ++i) {
uint32_t const index = fnv_hash(s_mix->words[0] ^ i, mix->words[i % MIX_WORDS]) % num_full_pages;
for (unsigned n = 0; n != MIX_NODES; ++n) {
@ -211,7 +247,7 @@ static bool ethash_hash(
dag_node = &full_nodes[MIX_NODES * index + n];
} else {
node tmp_node;
ethash_calculate_dag_item(&tmp_node, index * MIX_NODES + n, light);
ubqhash_calculate_dag_item(&tmp_node, index * MIX_NODES + n, light);
dag_node = &tmp_node;
}
@ -254,11 +290,11 @@ static bool ethash_hash(
return true;
}
void ethash_quick_hash(
ethash_h256_t* return_hash,
ethash_h256_t const* header_hash,
void ubqhash_quick_hash(
ubqhash_h256_t* return_hash,
ubqhash_h256_t const* header_hash,
uint64_t nonce,
ethash_h256_t const* mix_hash
ubqhash_h256_t const* mix_hash
)
{
uint8_t buf[64 + 32];
@ -270,32 +306,32 @@ void ethash_quick_hash(
SHA3_256(return_hash, buf, 64 + 32);
}
ethash_h256_t ethash_get_seedhash(uint64_t block_number)
ubqhash_h256_t ubqhash_get_seedhash(uint64_t block_number)
{
ethash_h256_t ret;
ethash_h256_reset(&ret);
uint64_t const epochs = block_number / ETHASH_EPOCH_LENGTH;
ubqhash_h256_t ret;
ubqhash_h256_reset(&ret);
uint64_t const epochs = block_number / UBQHASH_EPOCH_LENGTH;
for (uint32_t i = 0; i < epochs; ++i)
SHA3_256(&ret, (uint8_t*)&ret, 32);
return ret;
}
bool ethash_quick_check_difficulty(
ethash_h256_t const* header_hash,
bool ubqhash_quick_check_difficulty(
ubqhash_h256_t const* header_hash,
uint64_t const nonce,
ethash_h256_t const* mix_hash,
ethash_h256_t const* boundary
ubqhash_h256_t const* mix_hash,
ubqhash_h256_t const* boundary
)
{
ethash_h256_t return_hash;
ethash_quick_hash(&return_hash, header_hash, nonce, mix_hash);
return ethash_check_difficulty(&return_hash, boundary);
ubqhash_h256_t return_hash;
ubqhash_quick_hash(&return_hash, header_hash, nonce, mix_hash);
return ubqhash_check_difficulty(&return_hash, boundary);
}
ethash_light_t ethash_light_new_internal(uint64_t cache_size, ethash_h256_t const* seed)
ubqhash_light_t ubqhash_light_new_internal(uint64_t cache_size, ubqhash_h256_t const* seed, bool uip1)
{
struct ethash_light *ret;
struct ubqhash_light *ret;
ret = calloc(sizeof(*ret), 1);
if (!ret) {
return NULL;
@ -305,9 +341,15 @@ ethash_light_t ethash_light_new_internal(uint64_t cache_size, ethash_h256_t cons
goto fail_free_light;
}
node* nodes = (node*)ret->cache;
if (!ethash_compute_cache_nodes(nodes, cache_size, seed)) {
if (uip1) {
if (!ubqhash_compute_cache_nodes_uip1(nodes, cache_size, seed)) {
goto fail_free_cache_mem;
}
} else {
if (!ubqhash_compute_cache_nodes(nodes, cache_size, seed)) {
goto fail_free_cache_mem;
}
}
ret->cache_size = cache_size;
return ret;
@ -318,16 +360,20 @@ fail_free_light:
return NULL;
}
ethash_light_t ethash_light_new(uint64_t block_number)
ubqhash_light_t ubqhash_light_new(uint64_t block_number)
{
ethash_h256_t seedhash = ethash_get_seedhash(block_number);
ethash_light_t ret;
ret = ethash_light_new_internal(ethash_get_cachesize(block_number), &seedhash);
ubqhash_h256_t seedhash = ubqhash_get_seedhash(block_number);
ubqhash_light_t ret;
if (block_number >= UBQHASH_EPOCH_LENGTH * UBQHASH_UIP1_EPOCH) {
ret = ubqhash_light_new_internal(ubqhash_get_cachesize(block_number), &seedhash, true);
} else {
ret = ubqhash_light_new_internal(ubqhash_get_cachesize(block_number), &seedhash, false);
}
ret->block_number = block_number;
return ret;
}
void ethash_light_delete(ethash_light_t light)
void ubqhash_light_delete(ubqhash_light_t light)
{
if (light->cache) {
free(light->cache);
@ -335,43 +381,43 @@ void ethash_light_delete(ethash_light_t light)
free(light);
}
ethash_return_value_t ethash_light_compute_internal(
ethash_light_t light,
ubqhash_return_value_t ubqhash_light_compute_internal(
ubqhash_light_t light,
uint64_t full_size,
ethash_h256_t const header_hash,
ubqhash_h256_t const header_hash,
uint64_t nonce
)
{
ethash_return_value_t ret;
ubqhash_return_value_t ret;
ret.success = true;
if (!ethash_hash(&ret, NULL, light, full_size, header_hash, nonce)) {
if (!ubqhash_hash(&ret, NULL, light, full_size, header_hash, nonce)) {
ret.success = false;
}
return ret;
}
ethash_return_value_t ethash_light_compute(
ethash_light_t light,
ethash_h256_t const header_hash,
ubqhash_return_value_t ubqhash_light_compute(
ubqhash_light_t light,
ubqhash_h256_t const header_hash,
uint64_t nonce
)
{
uint64_t full_size = ethash_get_datasize(light->block_number);
return ethash_light_compute_internal(light, full_size, header_hash, nonce);
uint64_t full_size = ubqhash_get_datasize(light->block_number);
return ubqhash_light_compute_internal(light, full_size, header_hash, nonce);
}
static bool ethash_mmap(struct ethash_full* ret, FILE* f)
static bool ubqhash_mmap(struct ubqhash_full* ret, FILE* f)
{
int fd;
char* mmapped_data;
errno = 0;
ret->file = f;
if ((fd = ethash_fileno(ret->file)) == -1) {
if ((fd = ubqhash_fileno(ret->file)) == -1) {
return false;
}
mmapped_data= mmap(
NULL,
(size_t)ret->file_size + ETHASH_DAG_MAGIC_NUM_SIZE,
(size_t)ret->file_size + UBQHASH_DAG_MAGIC_NUM_SIZE,
PROT_READ | PROT_WRITE,
MAP_SHARED,
fd,
@ -380,67 +426,67 @@ static bool ethash_mmap(struct ethash_full* ret, FILE* f)
if (mmapped_data == MAP_FAILED) {
return false;
}
ret->data = (node*)(mmapped_data + ETHASH_DAG_MAGIC_NUM_SIZE);
ret->data = (node*)(mmapped_data + UBQHASH_DAG_MAGIC_NUM_SIZE);
return true;
}
ethash_full_t ethash_full_new_internal(
ubqhash_full_t ubqhash_full_new_internal(
char const* dirname,
ethash_h256_t const seed_hash,
ubqhash_h256_t const seed_hash,
uint64_t full_size,
ethash_light_t const light,
ethash_callback_t callback
ubqhash_light_t const light,
ubqhash_callback_t callback
)
{
struct ethash_full* ret;
struct ubqhash_full* ret;
FILE *f = NULL;
ret = calloc(sizeof(*ret), 1);
if (!ret) {
return NULL;
}
ret->file_size = (size_t)full_size;
switch (ethash_io_prepare(dirname, seed_hash, &f, (size_t)full_size, false)) {
case ETHASH_IO_FAIL:
// ethash_io_prepare will do all ETHASH_CRITICAL() logging in fail case
switch (ubqhash_io_prepare(dirname, seed_hash, &f, (size_t)full_size, false)) {
case UBQHASH_IO_FAIL:
// ubqhash_io_prepare will do all UBQHASH_CRITICAL() logging in fail case
goto fail_free_full;
case ETHASH_IO_MEMO_MATCH:
if (!ethash_mmap(ret, f)) {
ETHASH_CRITICAL("mmap failure()");
case UBQHASH_IO_MEMO_MATCH:
if (!ubqhash_mmap(ret, f)) {
UBQHASH_CRITICAL("mmap failure()");
goto fail_close_file;
}
return ret;
case ETHASH_IO_MEMO_SIZE_MISMATCH:
case UBQHASH_IO_MEMO_SIZE_MISMATCH:
// if a DAG of same filename but unexpected size is found, silently force new file creation
if (ethash_io_prepare(dirname, seed_hash, &f, (size_t)full_size, true) != ETHASH_IO_MEMO_MISMATCH) {
ETHASH_CRITICAL("Could not recreate DAG file after finding existing DAG with unexpected size.");
if (ubqhash_io_prepare(dirname, seed_hash, &f, (size_t)full_size, true) != UBQHASH_IO_MEMO_MISMATCH) {
UBQHASH_CRITICAL("Could not recreate DAG file after finding existing DAG with unexpected size.");
goto fail_free_full;
}
// fallthrough to the mismatch case here, DO NOT go through match
case ETHASH_IO_MEMO_MISMATCH:
if (!ethash_mmap(ret, f)) {
ETHASH_CRITICAL("mmap failure()");
case UBQHASH_IO_MEMO_MISMATCH:
if (!ubqhash_mmap(ret, f)) {
UBQHASH_CRITICAL("mmap failure()");
goto fail_close_file;
}
break;
}
if (!ethash_compute_full_data(ret->data, full_size, light, callback)) {
ETHASH_CRITICAL("Failure at computing DAG data.");
if (!ubqhash_compute_full_data(ret->data, full_size, light, callback)) {
UBQHASH_CRITICAL("Failure at computing DAG data.");
goto fail_free_full_data;
}
// after the DAG has been filled then we finalize it by writting the magic number at the beginning
if (fseek(f, 0, SEEK_SET) != 0) {
ETHASH_CRITICAL("Could not seek to DAG file start to write magic number.");
UBQHASH_CRITICAL("Could not seek to DAG file start to write magic number.");
goto fail_free_full_data;
}
uint64_t const magic_num = ETHASH_DAG_MAGIC_NUM;
if (fwrite(&magic_num, ETHASH_DAG_MAGIC_NUM_SIZE, 1, f) != 1) {
ETHASH_CRITICAL("Could not write magic number to DAG's beginning.");
uint64_t const magic_num = UBQHASH_DAG_MAGIC_NUM;
if (fwrite(&magic_num, UBQHASH_DAG_MAGIC_NUM_SIZE, 1, f) != 1) {
UBQHASH_CRITICAL("Could not write magic number to DAG's beginning.");
goto fail_free_full_data;
}
if (fflush(f) != 0) {// make sure the magic number IS there
ETHASH_CRITICAL("Could not flush memory mapped data to DAG file. Insufficient space?");
UBQHASH_CRITICAL("Could not flush memory mapped data to DAG file. Insufficient space?");
goto fail_free_full_data;
}
return ret;
@ -455,18 +501,18 @@ fail_free_full:
return NULL;
}
ethash_full_t ethash_full_new(ethash_light_t light, ethash_callback_t callback)
ubqhash_full_t ubqhash_full_new(ubqhash_light_t light, ubqhash_callback_t callback)
{
char strbuf[256];
if (!ethash_get_default_dirname(strbuf, 256)) {
if (!ubqhash_get_default_dirname(strbuf, 256)) {
return NULL;
}
uint64_t full_size = ethash_get_datasize(light->block_number);
ethash_h256_t seedhash = ethash_get_seedhash(light->block_number);
return ethash_full_new_internal(strbuf, seedhash, full_size, light, callback);
uint64_t full_size = ubqhash_get_datasize(light->block_number);
ubqhash_h256_t seedhash = ubqhash_get_seedhash(light->block_number);
return ubqhash_full_new_internal(strbuf, seedhash, full_size, light, callback);
}
void ethash_full_delete(ethash_full_t full)
void ubqhash_full_delete(ubqhash_full_t full)
{
// could check that munmap(..) == 0 but even if it did not can't really do anything here
munmap(full->data, (size_t)full->file_size);
@ -476,15 +522,15 @@ void ethash_full_delete(ethash_full_t full)
free(full);
}
ethash_return_value_t ethash_full_compute(
ethash_full_t full,
ethash_h256_t const header_hash,
ubqhash_return_value_t ubqhash_full_compute(
ubqhash_full_t full,
ubqhash_h256_t const header_hash,
uint64_t nonce
)
{
ethash_return_value_t ret;
ubqhash_return_value_t ret;
ret.success = true;
if (!ethash_hash(
if (!ubqhash_hash(
&ret,
(node const*)full->data,
NULL,
@ -496,12 +542,12 @@ ethash_return_value_t ethash_full_compute(
return ret;
}
void const* ethash_full_dag(ethash_full_t full)
void const* ubqhash_full_dag(ubqhash_full_t full)
{
return full->data;
}
uint64_t ethash_full_dag_size(ethash_full_t full)
uint64_t ubqhash_full_dag_size(ubqhash_full_t full)
{
return full->file_size;
}

View file

@ -1,7 +1,7 @@
#pragma once
#include "compiler.h"
#include "endian.h"
#include "ethash.h"
#include "ubqhash.h"
#include <stdio.h>
#define ENABLE_SSE 0
@ -16,7 +16,7 @@ extern "C" {
// compile time settings
#define NODE_WORDS (64/4)
#define MIX_WORDS (ETHASH_MIX_BYTES/4)
#define MIX_WORDS (UBQHASH_MIX_BYTES/4)
#define MIX_NODES (MIX_WORDS / NODE_WORDS)
#include <stdint.h>
@ -31,33 +31,33 @@ typedef union node {
} node;
static inline uint8_t ethash_h256_get(ethash_h256_t const* hash, unsigned int i)
static inline uint8_t ubqhash_h256_get(ubqhash_h256_t const* hash, unsigned int i)
{
return hash->b[i];
}
static inline void ethash_h256_set(ethash_h256_t* hash, unsigned int i, uint8_t v)
static inline void ubqhash_h256_set(ubqhash_h256_t* hash, unsigned int i, uint8_t v)
{
hash->b[i] = v;
}
static inline void ethash_h256_reset(ethash_h256_t* hash)
static inline void ubqhash_h256_reset(ubqhash_h256_t* hash)
{
memset(hash, 0, 32);
}
// Returns if hash is less than or equal to boundary (2^256/difficulty)
static inline bool ethash_check_difficulty(
ethash_h256_t const* hash,
ethash_h256_t const* boundary
static inline bool ubqhash_check_difficulty(
ubqhash_h256_t const* hash,
ubqhash_h256_t const* boundary
)
{
// Boundary is big endian
for (int i = 0; i < 32; i++) {
if (ethash_h256_get(hash, i) == ethash_h256_get(boundary, i)) {
if (ubqhash_h256_get(hash, i) == ubqhash_h256_get(boundary, i)) {
continue;
}
return ethash_h256_get(hash, i) < ethash_h256_get(boundary, i);
return ubqhash_h256_get(hash, i) < ubqhash_h256_get(boundary, i);
}
return true;
}
@ -71,29 +71,29 @@ static inline bool ethash_check_difficulty(
* @param boundary The boundary is defined as (2^256 / difficulty)
* @return true for succesful pre-verification and false otherwise
*/
bool ethash_quick_check_difficulty(
ethash_h256_t const* header_hash,
bool ubqhash_quick_check_difficulty(
ubqhash_h256_t const* header_hash,
uint64_t const nonce,
ethash_h256_t const* mix_hash,
ethash_h256_t const* boundary
ubqhash_h256_t const* mix_hash,
ubqhash_h256_t const* boundary
);
struct ethash_light {
struct ubqhash_light {
void* cache;
uint64_t cache_size;
uint64_t block_number;
};
/**
* Allocate and initialize a new ethash_light handler. Internal version
* Allocate and initialize a new ubqhash_light handler. Internal version
*
* @param cache_size The size of the cache in bytes
* @param seed Block seedhash to be used during the computation of the
* cache nodes
* @return Newly allocated ethash_light handler or NULL in case of
* ERRNOMEM or invalid parameters used for @ref ethash_compute_cache_nodes()
* @return Newly allocated ubqhash_light handler or NULL in case of
* ERRNOMEM or invalid parameters used for @ref ubqhash_compute_cache_nodes()
*/
ethash_light_t ethash_light_new_internal(uint64_t cache_size, ethash_h256_t const* seed);
ubqhash_light_t ubqhash_light_new_internal(uint64_t cache_size, ubqhash_h256_t const* seed, bool uip1);
/**
* Calculate the light client data. Internal version.
@ -104,74 +104,74 @@ ethash_light_t ethash_light_new_internal(uint64_t cache_size, ethash_h256_t cons
* @param nonce The nonce to pack into the mix
* @return The resulting hash.
*/
ethash_return_value_t ethash_light_compute_internal(
ethash_light_t light,
ubqhash_return_value_t ubqhash_light_compute_internal(
ubqhash_light_t light,
uint64_t full_size,
ethash_h256_t const header_hash,
ubqhash_h256_t const header_hash,
uint64_t nonce
);
struct ethash_full {
struct ubqhash_full {
FILE* file;
uint64_t file_size;
node* data;
};
/**
* Allocate and initialize a new ethash_full handler. Internal version.
* Allocate and initialize a new ubqhash_full handler. Internal version.
*
* @param dirname The directory in which to put the DAG file.
* @param seedhash The seed hash of the block. Used in the DAG file naming.
* @param full_size The size of the full data in bytes.
* @param cache A cache object to use that was allocated with @ref ethash_cache_new().
* Iff this function succeeds the ethash_full_t will take memory
* @param cache A cache object to use that was allocated with @ref ubqhash_cache_new().
* Iff this function succeeds the ubqhash_full_t will take memory
* memory ownership of the cache and free it at deletion. If
* not then the user still has to handle freeing of the cache himself.
* @param callback A callback function with signature of @ref ethash_callback_t
* @param callback A callback function with signature of @ref ubqhash_callback_t
* It accepts an unsigned with which a progress of DAG calculation
* can be displayed. If all goes well the callback should return 0.
* If a non-zero value is returned then DAG generation will stop.
* @return Newly allocated ethash_full handler or NULL in case of
* ERRNOMEM or invalid parameters used for @ref ethash_compute_full_data()
* @return Newly allocated ubqhash_full handler or NULL in case of
* ERRNOMEM or invalid parameters used for @ref ubqhash_compute_full_data()
*/
ethash_full_t ethash_full_new_internal(
ubqhash_full_t ubqhash_full_new_internal(
char const* dirname,
ethash_h256_t const seed_hash,
ubqhash_h256_t const seed_hash,
uint64_t full_size,
ethash_light_t const light,
ethash_callback_t callback
ubqhash_light_t const light,
ubqhash_callback_t callback
);
void ethash_calculate_dag_item(
void ubqhash_calculate_dag_item(
node* const ret,
uint32_t node_index,
ethash_light_t const cache
ubqhash_light_t const cache
);
void ethash_quick_hash(
ethash_h256_t* return_hash,
ethash_h256_t const* header_hash,
void ubqhash_quick_hash(
ubqhash_h256_t* return_hash,
ubqhash_h256_t const* header_hash,
const uint64_t nonce,
ethash_h256_t const* mix_hash
ubqhash_h256_t const* mix_hash
);
uint64_t ethash_get_datasize(uint64_t const block_number);
uint64_t ethash_get_cachesize(uint64_t const block_number);
uint64_t ubqhash_get_datasize(uint64_t const block_number);
uint64_t ubqhash_get_cachesize(uint64_t const block_number);
/**
* Compute the memory data for a full node's memory
*
* @param mem A pointer to an ethash full's memory
* @param mem A pointer to an ubqhash full's memory
* @param full_size The size of the full data in bytes
* @param cache A cache object to use in the calculation
* @param callback The callback function. Check @ref ethash_full_new() for details.
* @param callback The callback function. Check @ref ubqhash_full_new() for details.
* @return true if all went fine and false for invalid parameters
*/
bool ethash_compute_full_data(
bool ubqhash_compute_full_data(
void* mem,
uint64_t full_size,
ethash_light_t const light,
ethash_callback_t callback
ubqhash_light_t const light,
ubqhash_callback_t callback
);
#ifdef __cplusplus

119
vendor/github.com/ubiq/ubqhash/src/libubqhash/io.c generated vendored Normal file
View file

@ -0,0 +1,119 @@
/*
This file is part of ubqhash.
ubqhash is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ubqhash is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with ubqhash. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file io.c
* @author Lefteris Karapetsas <lefteris@ethdev.com>
* @date 2015
*/
#include "io.h"
#include <string.h>
#include <stdio.h>
#include <errno.h>
enum ubqhash_io_rc ubqhash_io_prepare(
char const* dirname,
ubqhash_h256_t const seedhash,
FILE** output_file,
uint64_t file_size,
bool force_create
)
{
char mutable_name[DAG_MUTABLE_NAME_MAX_SIZE];
enum ubqhash_io_rc ret = UBQHASH_IO_FAIL;
// reset errno before io calls
errno = 0;
// assert directory exists
if (!ubqhash_mkdir(dirname)) {
UBQHASH_CRITICAL("Could not create the ubqhash directory");
goto end;
}
ubqhash_io_mutable_name(UBQHASH_REVISION, &seedhash, mutable_name);
char* tmpfile = ubqhash_io_create_filename(dirname, mutable_name, strlen(mutable_name));
if (!tmpfile) {
UBQHASH_CRITICAL("Could not create the full DAG pathname");
goto end;
}
FILE *f;
if (!force_create) {
// try to open the file
f = ubqhash_fopen(tmpfile, "rb+");
if (f) {
size_t found_size;
if (!ubqhash_file_size(f, &found_size)) {
fclose(f);
UBQHASH_CRITICAL("Could not query size of DAG file: \"%s\"", tmpfile);
goto free_memo;
}
if (file_size != found_size - UBQHASH_DAG_MAGIC_NUM_SIZE) {
fclose(f);
ret = UBQHASH_IO_MEMO_SIZE_MISMATCH;
goto free_memo;
}
// compare the magic number, no need to care about endianess since it's local
uint64_t magic_num;
if (fread(&magic_num, UBQHASH_DAG_MAGIC_NUM_SIZE, 1, f) != 1) {
// I/O error
fclose(f);
UBQHASH_CRITICAL("Could not read from DAG file: \"%s\"", tmpfile);
ret = UBQHASH_IO_MEMO_SIZE_MISMATCH;
goto free_memo;
}
if (magic_num != UBQHASH_DAG_MAGIC_NUM) {
fclose(f);
ret = UBQHASH_IO_MEMO_SIZE_MISMATCH;
goto free_memo;
}
ret = UBQHASH_IO_MEMO_MATCH;
goto set_file;
}
}
// file does not exist, will need to be created
f = ubqhash_fopen(tmpfile, "wb+");
if (!f) {
UBQHASH_CRITICAL("Could not create DAG file: \"%s\"", tmpfile);
goto free_memo;
}
// make sure it's of the proper size
if (fseek(f, (long int)(file_size + UBQHASH_DAG_MAGIC_NUM_SIZE - 1), SEEK_SET) != 0) {
fclose(f);
UBQHASH_CRITICAL("Could not seek to the end of DAG file: \"%s\". Insufficient space?", tmpfile);
goto free_memo;
}
if (fputc('\n', f) == EOF) {
fclose(f);
UBQHASH_CRITICAL("Could not write in the end of DAG file: \"%s\". Insufficient space?", tmpfile);
goto free_memo;
}
if (fflush(f) != 0) {
fclose(f);
UBQHASH_CRITICAL("Could not flush at end of DAG file: \"%s\". Insufficient space?", tmpfile);
goto free_memo;
}
ret = UBQHASH_IO_MEMO_MISMATCH;
goto set_file;
ret = UBQHASH_IO_MEMO_MATCH;
set_file:
*output_file = f;
free_memo:
free(tmpfile);
end:
return ret;
}

View file

@ -1,18 +1,18 @@
/*
This file is part of ethash.
This file is part of ubqhash.
ethash is free software: you can redistribute it and/or modify
ubqhash is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ethash is distributed in the hope that it will be useful,
ubqhash is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with ethash. If not, see <http://www.gnu.org/licenses/>.
along with ubqhash. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file io.h
* @author Lefteris Karapetsas <lefteris@ethdev.com>
@ -28,7 +28,7 @@
#endif
#include <inttypes.h>
#include "endian.h"
#include "ethash.h"
#include "ubqhash.h"
#ifdef __cplusplus
extern "C" {
@ -38,14 +38,14 @@ extern "C" {
// 10 is for maximum number of digits of a uint32_t (for REVISION)
// 1 is for - and 16 is for the first 16 hex digits for first 8 bytes of
// the seedhash and last 1 is for the null terminating character
// Reference: https://github.com/ubiq/wiki/wiki/Ethash-DAG
// Reference: https://github.com/ethereum/wiki/wiki/Ubqhash-DAG
#define DAG_MUTABLE_NAME_MAX_SIZE (6 + 10 + 1 + 16 + 1)
/// Possible return values of @see ethash_io_prepare
enum ethash_io_rc {
ETHASH_IO_FAIL = 0, ///< There has been an IO failure
ETHASH_IO_MEMO_SIZE_MISMATCH, ///< DAG with revision/hash match, but file size was wrong.
ETHASH_IO_MEMO_MISMATCH, ///< The DAG file did not exist or there was revision/hash mismatch
ETHASH_IO_MEMO_MATCH, ///< DAG file existed and revision/hash matched. No need to do anything
/// Possible return values of @see ubqhash_io_prepare
enum ubqhash_io_rc {
UBQHASH_IO_FAIL = 0, ///< There has been an IO failure
UBQHASH_IO_MEMO_SIZE_MISMATCH, ///< DAG with revision/hash match, but file size was wrong.
UBQHASH_IO_MEMO_MISMATCH, ///< The DAG file did not exist or there was revision/hash mismatch
UBQHASH_IO_MEMO_MATCH, ///< DAG file existed and revision/hash matched. No need to do anything
};
// small hack for windows. I don't feel I should use va_args and forward just
@ -55,32 +55,32 @@ enum ethash_io_rc {
#endif
/**
* Logs a critical error in important parts of ethash. Should mostly help
* Logs a critical error in important parts of ubqhash. Should mostly help
* figure out what kind of problem (I/O, memory e.t.c.) causes a NULL
* ethash_full_t
* ubqhash_full_t
*/
#ifdef ETHASH_PRINT_CRITICAL_OUTPUT
#define ETHASH_CRITICAL(...) \
#ifdef UBQHASH_PRINT_CRITICAL_OUTPUT
#define UBQHASH_CRITICAL(...) \
do \
{ \
printf("ETHASH CRITICAL ERROR: "__VA_ARGS__); \
printf("UBQHASH CRITICAL ERROR: "__VA_ARGS__); \
printf("\n"); \
fflush(stdout); \
} while (0)
#else
#define ETHASH_CRITICAL(...)
#define UBQHASH_CRITICAL(...)
#endif
/**
* Prepares io for ethash
* Prepares io for ubqhash
*
* Create the DAG directory and the DAG file if they don't exist.
*
* @param[in] dirname A null terminated c-string of the path of the ethash
* @param[in] dirname A null terminated c-string of the path of the ubqhash
* data directory. If it does not exist it's created.
* @param[in] seedhash The seedhash of the current block number, used in the
* naming of the file as can be seen from the spec at:
* https://github.com/ubiq/wiki/wiki/Ethash-DAG
* https://github.com/ethereum/wiki/wiki/Ubqhash-DAG
* @param[out] output_file If there was no failure then this will point to an open
* file descriptor. User is responsible for closing it.
* In the case of memo match then the file is open on read
@ -89,11 +89,11 @@ enum ethash_io_rc {
* @param[in] file_size The size that the DAG file should have on disk
* @param[out] force_create If true then there is no check to see if the file
* already exists
* @return For possible return values @see enum ethash_io_rc
* @return For possible return values @see enum ubqhash_io_rc
*/
enum ethash_io_rc ethash_io_prepare(
enum ubqhash_io_rc ubqhash_io_prepare(
char const* dirname,
ethash_h256_t const seedhash,
ubqhash_h256_t const seedhash,
FILE** output_file,
uint64_t file_size,
bool force_create
@ -111,7 +111,7 @@ enum ethash_io_rc ethash_io_prepare(
* @param mode Opening mode. Check fopen()
* @return The FILE* or NULL in failure
*/
FILE* ethash_fopen(char const* file_name, char const* mode);
FILE* ubqhash_fopen(char const* file_name, char const* mode);
/**
* An strncat wrapper for no-warnings crossplatform strncat.
@ -129,7 +129,7 @@ FILE* ethash_fopen(char const* file_name, char const* mode);
* @return If all is well returns the dest buffer. If there is an
* error returns NULL
*/
char* ethash_strncat(char* dest, size_t dest_size, char const* src, size_t count);
char* ubqhash_strncat(char* dest, size_t dest_size, char const* src, size_t count);
/**
* A cross-platform mkdir wrapper to create a directory or assert it's there
@ -138,7 +138,7 @@ char* ethash_strncat(char* dest, size_t dest_size, char const* src, size_t count
* @return true if the directory was created or if it already
* existed
*/
bool ethash_mkdir(char const* dirname);
bool ubqhash_mkdir(char const* dirname);
/**
* Get a file's size
@ -147,7 +147,7 @@ bool ethash_mkdir(char const* dirname);
* @param[out] size Pass a size_t by reference to contain the file size
* @return true in success and false if there was a failure
*/
bool ethash_file_size(FILE* f, size_t* ret_size);
bool ubqhash_file_size(FILE* f, size_t* ret_size);
/**
* Get a file descriptor number from a FILE stream
@ -155,7 +155,7 @@ bool ethash_file_size(FILE* f, size_t* ret_size);
* @param f The file stream whose fd to get
* @return Platform specific fd handler
*/
int ethash_fileno(FILE* f);
int ubqhash_fileno(FILE* f);
/**
* Create the filename for the DAG.
@ -166,7 +166,7 @@ int ethash_fileno(FILE* f);
* @param filename_length The length of the filename in bytes
* @return A char* containing the full name. User must deallocate.
*/
char* ethash_io_create_filename(
char* ubqhash_io_create_filename(
char const* dirname,
char const* filename,
size_t filename_length
@ -175,24 +175,24 @@ char* ethash_io_create_filename(
/**
* Gets the default directory name for the DAG depending on the system
*
* The spec defining this directory is here: https://github.com/ubiq/wiki/wiki/Ethash-DAG
* The spec defining this directory is here: https://github.com/ethereum/wiki/wiki/Ubqhash-DAG
*
* @param[out] strbuf A string buffer of sufficient size to keep the
* null termninated string of the directory name
* @param[in] buffsize Size of @a strbuf in bytes
* @return true for success and false otherwise
*/
bool ethash_get_default_dirname(char* strbuf, size_t buffsize);
bool ubqhash_get_default_dirname(char* strbuf, size_t buffsize);
static inline bool ethash_io_mutable_name(
static inline bool ubqhash_io_mutable_name(
uint32_t revision,
ethash_h256_t const* seed_hash,
ubqhash_h256_t const* seed_hash,
char* output
)
{
uint64_t hash = *((uint64_t*)seed_hash);
#if LITTLE_ENDIAN == BYTE_ORDER
hash = ethash_swap_u64(hash);
hash = ubqhash_swap_u64(hash);
#endif
return snprintf(output, DAG_MUTABLE_NAME_MAX_SIZE, "full-R%u-%016" PRIx64, revision, hash) >= 0;
}

View file

@ -1,18 +1,18 @@
/*
This file is part of ethash.
This file is part of ubqhash.
ethash is free software: you can redistribute it and/or modify
ubqhash is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ethash is distributed in the hope that it will be useful,
ubqhash is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with ethash. If not, see <http://www.gnu.org/licenses/>.
along with ubqhash. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file io_posix.c
* @author Lefteris Karapetsas <lefteris@ethdev.com>
@ -29,28 +29,28 @@
#include <stdlib.h>
#include <pwd.h>
FILE* ethash_fopen(char const* file_name, char const* mode)
FILE* ubqhash_fopen(char const* file_name, char const* mode)
{
return fopen(file_name, mode);
}
char* ethash_strncat(char* dest, size_t dest_size, char const* src, size_t count)
char* ubqhash_strncat(char* dest, size_t dest_size, char const* src, size_t count)
{
return strlen(dest) + count + 1 <= dest_size ? strncat(dest, src, count) : NULL;
}
bool ethash_mkdir(char const* dirname)
bool ubqhash_mkdir(char const* dirname)
{
int rc = mkdir(dirname, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
return rc != -1 || errno == EEXIST;
}
int ethash_fileno(FILE *f)
int ubqhash_fileno(FILE *f)
{
return fileno(f);
}
char* ethash_io_create_filename(
char* ubqhash_io_create_filename(
char const* dirname,
char const* filename,
size_t filename_length
@ -67,15 +67,15 @@ char* ethash_io_create_filename(
}
name[0] = '\0';
ethash_strncat(name, dest_size, dirname, dirlen);
ubqhash_strncat(name, dest_size, dirname, dirlen);
if (dirname[dirlen] != '/') {
ethash_strncat(name, dest_size, "/", 1);
ubqhash_strncat(name, dest_size, "/", 1);
}
ethash_strncat(name, dest_size, filename, filename_length);
ubqhash_strncat(name, dest_size, filename, filename_length);
return name;
}
bool ethash_file_size(FILE* f, size_t* ret_size)
bool ubqhash_file_size(FILE* f, size_t* ret_size)
{
struct stat st;
int fd;
@ -86,9 +86,9 @@ bool ethash_file_size(FILE* f, size_t* ret_size)
return true;
}
bool ethash_get_default_dirname(char* strbuf, size_t buffsize)
bool ubqhash_get_default_dirname(char* strbuf, size_t buffsize)
{
static const char dir_suffix[] = ".ethash/";
static const char dir_suffix[] = ".ubqhash/";
strbuf[0] = '\0';
char* home_dir = getenv("HOME");
if (!home_dir || strlen(home_dir) == 0)
@ -99,13 +99,13 @@ bool ethash_get_default_dirname(char* strbuf, size_t buffsize)
}
size_t len = strlen(home_dir);
if (!ethash_strncat(strbuf, buffsize, home_dir, len)) {
if (!ubqhash_strncat(strbuf, buffsize, home_dir, len)) {
return false;
}
if (home_dir[len] != '/') {
if (!ethash_strncat(strbuf, buffsize, "/", 1)) {
if (!ubqhash_strncat(strbuf, buffsize, "/", 1)) {
return false;
}
}
return ethash_strncat(strbuf, buffsize, dir_suffix, sizeof(dir_suffix));
return ubqhash_strncat(strbuf, buffsize, dir_suffix, sizeof(dir_suffix));
}

View file

@ -1,18 +1,18 @@
/*
This file is part of ethash.
This file is part of ubqhash.
ethash is free software: you can redistribute it and/or modify
ubqhash is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ethash is distributed in the hope that it will be useful,
ubqhash is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with ethash. If not, see <http://www.gnu.org/licenses/>.
along with ubqhash. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file io_win32.c
* @author Lefteris Karapetsas <lefteris@ethdev.com>
@ -27,29 +27,29 @@
#include <sys/types.h>
#include <shlobj.h>
FILE* ethash_fopen(char const* file_name, char const* mode)
FILE* ubqhash_fopen(char const* file_name, char const* mode)
{
FILE* f;
return fopen_s(&f, file_name, mode) == 0 ? f : NULL;
}
char* ethash_strncat(char* dest, size_t dest_size, char const* src, size_t count)
char* ubqhash_strncat(char* dest, size_t dest_size, char const* src, size_t count)
{
return strncat_s(dest, dest_size, src, count) == 0 ? dest : NULL;
}
bool ethash_mkdir(char const* dirname)
bool ubqhash_mkdir(char const* dirname)
{
int rc = _mkdir(dirname);
return rc != -1 || errno == EEXIST;
}
int ethash_fileno(FILE* f)
int ubqhash_fileno(FILE* f)
{
return _fileno(f);
}
char* ethash_io_create_filename(
char* ubqhash_io_create_filename(
char const* dirname,
char const* filename,
size_t filename_length
@ -66,15 +66,15 @@ char* ethash_io_create_filename(
}
name[0] = '\0';
ethash_strncat(name, dest_size, dirname, dirlen);
ubqhash_strncat(name, dest_size, dirname, dirlen);
if (dirname[dirlen] != '\\' || dirname[dirlen] != '/') {
ethash_strncat(name, dest_size, "\\", 1);
ubqhash_strncat(name, dest_size, "\\", 1);
}
ethash_strncat(name, dest_size, filename, filename_length);
ubqhash_strncat(name, dest_size, filename, filename_length);
return name;
}
bool ethash_file_size(FILE* f, size_t* ret_size)
bool ubqhash_file_size(FILE* f, size_t* ret_size)
{
struct _stat st;
int fd;
@ -85,16 +85,16 @@ bool ethash_file_size(FILE* f, size_t* ret_size)
return true;
}
bool ethash_get_default_dirname(char* strbuf, size_t buffsize)
bool ubqhash_get_default_dirname(char* strbuf, size_t buffsize)
{
static const char dir_suffix[] = "Ethash\\";
static const char dir_suffix[] = "Ubqhash\\";
strbuf[0] = '\0';
if (!SUCCEEDED(SHGetFolderPathA(NULL, CSIDL_LOCAL_APPDATA, NULL, 0, (CHAR*)strbuf))) {
return false;
}
if (!ethash_strncat(strbuf, buffsize, "\\", 1)) {
if (!ubqhash_strncat(strbuf, buffsize, "\\", 1)) {
return false;
}
return ethash_strncat(strbuf, buffsize, dir_suffix, sizeof(dir_suffix));
return ubqhash_strncat(strbuf, buffsize, dir_suffix, sizeof(dir_suffix));
}

View file

@ -1,18 +1,18 @@
/*
This file is part of ethash.
This file is part of ubqhash.
ethash is free software: you can redistribute it and/or modify
ubqhash is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ethash is distributed in the hope that it will be useful,
ubqhash is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with ethash. If not, see <http://www.gnu.org/licenses/>.
along with ubqhash. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file mmap.h
* @author Lefteris Karapetsas <lefteris@ethdev.com>

View file

@ -8,7 +8,7 @@ extern "C" {
#include <stdint.h>
#include <stdlib.h>
struct ethash_h256;
struct ubqhash_h256;
#define decsha3(bits) \
int sha3_##bits(uint8_t*, size_t, uint8_t const*, size_t);
@ -16,7 +16,7 @@ struct ethash_h256;
decsha3(256)
decsha3(512)
static inline void SHA3_256(struct ethash_h256 const* ret, uint8_t const* data, size_t const size)
static inline void SHA3_256(struct ubqhash_h256 const* ret, uint8_t const* data, size_t const size)
{
sha3_256((uint8_t*)ret, 32, data, size);
}

View file

@ -1,18 +1,18 @@
/*
This file is part of ethash.
This file is part of ubqhash.
ethash is free software: you can redistribute it and/or modify
ubqhash is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ethash is distributed in the hope that it will be useful,
ubqhash is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with ethash. If not, see <http://www.gnu.org/licenses/>.
along with ubqhash. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file sha3.cpp
@ -23,9 +23,9 @@
#include <cryptopp/sha3.h>
extern "C" {
struct ethash_h256;
typedef struct ethash_h256 ethash_h256_t;
void SHA3_256(ethash_h256_t const* ret, uint8_t const* data, size_t size)
struct ubqhash_h256;
typedef struct ubqhash_h256 ubqhash_h256_t;
void SHA3_256(ubqhash_h256_t const* ret, uint8_t const* data, size_t size)
{
CryptoPP::SHA3_256().CalculateDigest((uint8_t*)ret, data, size);
}

View file

@ -8,9 +8,9 @@
extern "C" {
#endif
struct ethash_h256;
struct ubqhash_h256;
void SHA3_256(struct ethash_h256 const* ret, uint8_t const* data, size_t size);
void SHA3_256(struct ubqhash_h256 const* ret, uint8_t const* data, size_t size);
void SHA3_512(uint8_t* const ret, uint8_t const* data, size_t size);
#ifdef __cplusplus

View file

@ -1,21 +1,21 @@
/*
This file is part of ethash.
This file is part of ubqhash.
ethash is free software: you can redistribute it and/or modify
ubqhash is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ethash is distributed in the hope that it will be useful,
ubqhash is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with ethash. If not, see <http://www.gnu.org/licenses/>.
along with ubqhash. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file ethash.h
/** @file ubqhash.h
* @date 2015
*/
#pragma once
@ -26,121 +26,122 @@
#include <stddef.h>
#include "compiler.h"
#define ETHASH_REVISION 23
#define ETHASH_DATASET_BYTES_INIT 1073741824U // 2**30
#define ETHASH_DATASET_BYTES_GROWTH 8388608U // 2**23
#define ETHASH_CACHE_BYTES_INIT 1073741824U // 2**24
#define ETHASH_CACHE_BYTES_GROWTH 131072U // 2**17
#define ETHASH_EPOCH_LENGTH 30000U
#define ETHASH_MIX_BYTES 128
#define ETHASH_HASH_BYTES 64
#define ETHASH_DATASET_PARENTS 256
#define ETHASH_CACHE_ROUNDS 3
#define ETHASH_ACCESSES 64
#define ETHASH_DAG_MAGIC_NUM_SIZE 8
#define ETHASH_DAG_MAGIC_NUM 0xFEE1DEADBADDCAFE
#define UBQHASH_REVISION 23
#define UBQHASH_DATASET_BYTES_INIT 1073741824U // 2**30
#define UBQHASH_DATASET_BYTES_GROWTH 8388608U // 2**23
#define UBQHASH_CACHE_BYTES_INIT 1073741824U // 2**24
#define UBQHASH_CACHE_BYTES_GROWTH 131072U // 2**17
#define UBQHASH_EPOCH_LENGTH 30000U
#define UBQHASH_MIX_BYTES 128
#define UBQHASH_HASH_BYTES 64
#define UBQHASH_DATASET_PARENTS 256
#define UBQHASH_CACHE_ROUNDS 3
#define UBQHASH_ACCESSES 64
#define UBQHASH_DAG_MAGIC_NUM_SIZE 8
#define UBQHASH_DAG_MAGIC_NUM 0xFEE1DEADBADDCAFE
#define UBQHASH_UIP1_EPOCH 22
#ifdef __cplusplus
extern "C" {
#endif
/// Type of a seedhash/blockhash e.t.c.
typedef struct ethash_h256 { uint8_t b[32]; } ethash_h256_t;
typedef struct ubqhash_h256 { uint8_t b[32]; } ubqhash_h256_t;
// convenience macro to statically initialize an h256_t
// usage:
// ethash_h256_t a = ethash_h256_static_init(1, 2, 3, ... )
// ubqhash_h256_t a = ubqhash_h256_static_init(1, 2, 3, ... )
// have to provide all 32 values. If you don't provide all the rest
// will simply be unitialized (not guranteed to be 0)
#define ethash_h256_static_init(...) \
#define ubqhash_h256_static_init(...) \
{ {__VA_ARGS__} }
struct ethash_light;
typedef struct ethash_light* ethash_light_t;
struct ethash_full;
typedef struct ethash_full* ethash_full_t;
typedef int(*ethash_callback_t)(unsigned);
struct ubqhash_light;
typedef struct ubqhash_light* ubqhash_light_t;
struct ubqhash_full;
typedef struct ubqhash_full* ubqhash_full_t;
typedef int(*ubqhash_callback_t)(unsigned);
typedef struct ethash_return_value {
ethash_h256_t result;
ethash_h256_t mix_hash;
typedef struct ubqhash_return_value {
ubqhash_h256_t result;
ubqhash_h256_t mix_hash;
bool success;
} ethash_return_value_t;
} ubqhash_return_value_t;
/**
* Allocate and initialize a new ethash_light handler
* Allocate and initialize a new ubqhash_light handler
*
* @param block_number The block number for which to create the handler
* @return Newly allocated ethash_light handler or NULL in case of
* ERRNOMEM or invalid parameters used for @ref ethash_compute_cache_nodes()
* @return Newly allocated ubqhash_light handler or NULL in case of
* ERRNOMEM or invalid parameters used for @ref ubqhash_compute_cache_nodes()
*/
ethash_light_t ethash_light_new(uint64_t block_number);
ubqhash_light_t ubqhash_light_new(uint64_t block_number);
/**
* Frees a previously allocated ethash_light handler
* Frees a previously allocated ubqhash_light handler
* @param light The light handler to free
*/
void ethash_light_delete(ethash_light_t light);
void ubqhash_light_delete(ubqhash_light_t light);
/**
* Calculate the light client data
*
* @param light The light client handler
* @param header_hash The header hash to pack into the mix
* @param nonce The nonce to pack into the mix
* @return an object of ethash_return_value_t holding the return values
* @return an object of ubqhash_return_value_t holding the return values
*/
ethash_return_value_t ethash_light_compute(
ethash_light_t light,
ethash_h256_t const header_hash,
ubqhash_return_value_t ubqhash_light_compute(
ubqhash_light_t light,
ubqhash_h256_t const header_hash,
uint64_t nonce
);
/**
* Allocate and initialize a new ethash_full handler
* Allocate and initialize a new ubqhash_full handler
*
* @param light The light handler containing the cache.
* @param callback A callback function with signature of @ref ethash_callback_t
* @param callback A callback function with signature of @ref ubqhash_callback_t
* It accepts an unsigned with which a progress of DAG calculation
* can be displayed. If all goes well the callback should return 0.
* If a non-zero value is returned then DAG generation will stop.
* Be advised. A progress value of 100 means that DAG creation is
* almost complete and that this function will soon return succesfully.
* It does not mean that the function has already had a succesfull return.
* @return Newly allocated ethash_full handler or NULL in case of
* ERRNOMEM or invalid parameters used for @ref ethash_compute_full_data()
* @return Newly allocated ubqhash_full handler or NULL in case of
* ERRNOMEM or invalid parameters used for @ref ubqhash_compute_full_data()
*/
ethash_full_t ethash_full_new(ethash_light_t light, ethash_callback_t callback);
ubqhash_full_t ubqhash_full_new(ubqhash_light_t light, ubqhash_callback_t callback);
/**
* Frees a previously allocated ethash_full handler
* Frees a previously allocated ubqhash_full handler
* @param full The light handler to free
*/
void ethash_full_delete(ethash_full_t full);
void ubqhash_full_delete(ubqhash_full_t full);
/**
* Calculate the full client data
*
* @param full The full client handler
* @param header_hash The header hash to pack into the mix
* @param nonce The nonce to pack into the mix
* @return An object of ethash_return_value to hold the return value
* @return An object of ubqhash_return_value to hold the return value
*/
ethash_return_value_t ethash_full_compute(
ethash_full_t full,
ethash_h256_t const header_hash,
ubqhash_return_value_t ubqhash_full_compute(
ubqhash_full_t full,
ubqhash_h256_t const header_hash,
uint64_t nonce
);
/**
* Get a pointer to the full DAG data
*/
void const* ethash_full_dag(ethash_full_t full);
void const* ubqhash_full_dag(ubqhash_full_t full);
/**
* Get the size of the DAG data
*/
uint64_t ethash_full_dag_size(ethash_full_t full);
uint64_t ubqhash_full_dag_size(ubqhash_full_t full);
/**
* Calculate the seedhash for a given block number
*/
ethash_h256_t ethash_get_seedhash(uint64_t block_number);
ubqhash_h256_t ubqhash_get_seedhash(uint64_t block_number);
#ifdef __cplusplus
}

View file

@ -1,18 +1,18 @@
/*
This file is part of ethash.
This file is part of ubqhash.
ethash is free software: you can redistribute it and/or modify
ubqhash is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ethash is distributed in the hope that it will be useful,
ubqhash is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with ethash. If not, see <http://www.gnu.org/licenses/>.
along with ubqhash. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file util.h
* @author Tim Hughes <tim@twistedfury.com>

View file

@ -16,12 +16,12 @@
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package ethash
package ubqhash
/*
#include "src/libethash/internal.h"
#include "src/libubqhash/internal.h"
int ethashGoCallback_cgo(unsigned);
int ubqhashGoCallback_cgo(unsigned);
*/
import "C"
@ -56,6 +56,7 @@ const (
epochLength uint64 = 30000
cacheSizeForTesting C.uint64_t = 1024
dagSizeForTesting C.uint64_t = 1024 * 32
uip1Epoch uint64 = 22
)
var DefaultDir = defaultDir()
@ -66,12 +67,12 @@ func defaultDir() string {
home = user.HomeDir
}
if runtime.GOOS == "windows" {
return filepath.Join(home, "AppData", "Ethash")
return filepath.Join(home, "AppData", "Ubqhash")
}
return filepath.Join(home, ".ethash")
return filepath.Join(home, ".ubqhash")
}
// cache wraps an ethash_light_t with some metadata
// cache wraps an ubqhash_light_t with some metadata
// and automatic memory management.
type cache struct {
epoch uint64
@ -79,7 +80,7 @@ type cache struct {
test bool
gen sync.Once // ensures cache is only generated once.
ptr *C.struct_ethash_light
ptr *C.struct_ubqhash_light
}
// generate creates the actual cache. it can be called from multiple
@ -90,23 +91,27 @@ func (cache *cache) generate() {
started := time.Now()
seedHash := makeSeedHash(cache.epoch)
glog.V(logger.Debug).Infof("Generating cache for epoch %d (%x)", cache.epoch, seedHash)
size := C.ethash_get_cachesize(C.uint64_t(cache.epoch * epochLength))
size := C.ubqhash_get_cachesize(C.uint64_t(cache.epoch * epochLength))
if cache.test {
size = cacheSizeForTesting
}
cache.ptr = C.ethash_light_new_internal(size, (*C.ethash_h256_t)(unsafe.Pointer(&seedHash[0])))
if cache.epoch >= uip1Epoch {
cache.ptr = C.ubqhash_light_new_internal(size, (*C.ubqhash_h256_t)(unsafe.Pointer(&seedHash[0])), true)
} else {
cache.ptr = C.ubqhash_light_new_internal(size, (*C.ubqhash_h256_t)(unsafe.Pointer(&seedHash[0])), false)
}
runtime.SetFinalizer(cache, freeCache)
glog.V(logger.Debug).Infof("Done generating cache for epoch %d, it took %v", cache.epoch, time.Since(started))
})
}
func freeCache(cache *cache) {
C.ethash_light_delete(cache.ptr)
C.ubqhash_light_delete(cache.ptr)
cache.ptr = nil
}
func (cache *cache) compute(dagSize uint64, hash common.Hash, nonce uint64) (ok bool, mixDigest, result common.Hash) {
ret := C.ethash_light_compute_internal(cache.ptr, C.uint64_t(dagSize), hashToH256(hash), C.uint64_t(nonce))
ret := C.ubqhash_light_compute_internal(cache.ptr, C.uint64_t(dagSize), hashToH256(hash), C.uint64_t(nonce))
// Make sure cache is live until after the C call.
// This is important because a GC might happen and execute
// the finalizer before the call completes.
@ -128,11 +133,11 @@ type Light struct {
// Verify checks whether the block's nonce is valid.
func (l *Light) Verify(block pow.Block) bool {
// TODO: do ethash_quick_verify before getCache in order
// TODO: do ubqhash_quick_verify before getCache in order
// to prevent DOS attacks.
blockNum := block.NumberU64()
if blockNum >= epochLength*2048 {
glog.V(logger.Debug).Infof("block number %d too high, limit is %d", epochLength*2048)
glog.V(logger.Debug).Infof("block number %d too high, limit is %d", blockNum, epochLength*2048)
return false
}
@ -140,7 +145,7 @@ func (l *Light) Verify(block pow.Block) bool {
/* Cannot happen if block header diff is validated prior to PoW, but can
happen if PoW is checked first due to parallel PoW checking.
We could check the minimum valid difficulty but for SoC we avoid (duplicating)
Ethereum protocol consensus rules here which are not in scope of Ethash
Ethereum protocol consensus rules here which are not in scope of Ubqhash
*/
if difficulty.Cmp(common.Big0) == 0 {
glog.V(logger.Debug).Infof("invalid block difficulty")
@ -148,7 +153,7 @@ func (l *Light) Verify(block pow.Block) bool {
}
cache := l.getCache(blockNum)
dagSize := C.ethash_get_datasize(C.uint64_t(blockNum))
dagSize := C.ubqhash_get_datasize(C.uint64_t(blockNum))
if l.test {
dagSize = dagSizeForTesting
}
@ -168,12 +173,12 @@ func (l *Light) Verify(block pow.Block) bool {
return result.Big().Cmp(target) <= 0
}
func h256ToHash(in C.ethash_h256_t) common.Hash {
func h256ToHash(in C.ubqhash_h256_t) common.Hash {
return *(*common.Hash)(unsafe.Pointer(&in.b))
}
func hashToH256(in common.Hash) C.ethash_h256_t {
return C.ethash_h256_t{b: *(*[32]C.uint8_t)(unsafe.Pointer(&in[0]))}
func hashToH256(in common.Hash) C.ubqhash_h256_t {
return C.ubqhash_h256_t{b: *(*[32]C.uint8_t)(unsafe.Pointer(&in[0]))}
}
func (l *Light) getCache(blockNum uint64) *cache {
@ -226,7 +231,7 @@ func (l *Light) getCache(blockNum uint64) *cache {
return c
}
// dag wraps an ethash_full_t with some metadata
// dag wraps an ubqhash_full_t with some metadata
// and automatic memory management.
type dag struct {
epoch uint64
@ -234,7 +239,7 @@ type dag struct {
dir string
gen sync.Once // ensures DAG is only generated once.
ptr *C.struct_ethash_full
ptr *C.struct_ubqhash_full
}
// generate creates the actual DAG. it can be called from multiple
@ -246,8 +251,8 @@ func (d *dag) generate() {
started = time.Now()
seedHash = makeSeedHash(d.epoch)
blockNum = C.uint64_t(d.epoch * epochLength)
cacheSize = C.ethash_get_cachesize(blockNum)
dagSize = C.ethash_get_datasize(blockNum)
cacheSize = C.ubqhash_get_cachesize(blockNum)
dagSize = C.ubqhash_get_datasize(blockNum)
)
if d.test {
cacheSize = cacheSizeForTesting
@ -259,18 +264,23 @@ func (d *dag) generate() {
glog.V(logger.Info).Infof("Generating DAG for epoch %d (size %d) (%x)", d.epoch, dagSize, seedHash)
// Generate a temporary cache.
// TODO: this could share the cache with Light
cache := C.ethash_light_new_internal(cacheSize, (*C.ethash_h256_t)(unsafe.Pointer(&seedHash[0])))
defer C.ethash_light_delete(cache)
var cache C.ubqhash_light_t
if blockNum >= C.uint64_t(uip1Epoch*epochLength) {
cache = C.ubqhash_light_new_internal(cacheSize, (*C.ubqhash_h256_t)(unsafe.Pointer(&seedHash[0])), true)
} else {
cache = C.ubqhash_light_new_internal(cacheSize, (*C.ubqhash_h256_t)(unsafe.Pointer(&seedHash[0])), false)
}
defer C.ubqhash_light_delete(cache)
// Generate the actual DAG.
d.ptr = C.ethash_full_new_internal(
d.ptr = C.ubqhash_full_new_internal(
C.CString(d.dir),
hashToH256(seedHash),
dagSize,
cache,
(C.ethash_callback_t)(unsafe.Pointer(C.ethashGoCallback_cgo)),
(C.ubqhash_callback_t)(unsafe.Pointer(C.ubqhashGoCallback_cgo)),
)
if d.ptr == nil {
panic("ethash_full_new IO or memory error")
panic("ubqhash_full_new IO or memory error")
}
runtime.SetFinalizer(d, freeDAG)
glog.V(logger.Info).Infof("Done generating DAG for epoch %d, it took %v", d.epoch, time.Since(started))
@ -278,7 +288,7 @@ func (d *dag) generate() {
}
func freeDAG(d *dag) {
C.ethash_full_delete(d.ptr)
C.ubqhash_full_delete(d.ptr)
d.ptr = nil
}
@ -286,8 +296,8 @@ func (d *dag) Ptr() unsafe.Pointer {
return unsafe.Pointer(d.ptr.data)
}
//export ethashGoCallback
func ethashGoCallback(percent C.unsigned) C.int {
//export ubqhashGoCallback
func ubqhashGoCallback(percent C.unsigned) C.int {
glog.V(logger.Info).Infof("Generating DAG: %d%%", percent)
return 0
}
@ -366,10 +376,10 @@ func (pow *Full) Search(block pow.Block, stop <-chan struct{}, index int) (nonce
atomic.AddInt32(&pow.hashRate, hashrateDiff)
}
ret := C.ethash_full_compute(dag.ptr, hash, C.uint64_t(nonce))
ret := C.ubqhash_full_compute(dag.ptr, hash, C.uint64_t(nonce))
result := h256ToHash(ret.result).Big()
// TODO: disagrees with the spec https://github.com/ubiq/wiki/wiki/Ethash#mining
// TODO: disagrees with the spec https://github.com/ethereum/wiki/wiki/Ubqhash#mining
if ret.success && result.Cmp(target) <= 0 {
mixDigest = C.GoBytes(unsafe.Pointer(&ret.mix_hash), C.int(32))
atomic.AddInt32(&pow.hashRate, -previousHashrate)
@ -393,22 +403,22 @@ func (pow *Full) Turbo(on bool) {
pow.turbo = on
}
// Ethash combines block verification with Light and
// Ubqhash combines block verification with Light and
// nonce searching with Full into a single proof of work.
type Ethash struct {
type Ubqhash struct {
*Light
*Full
}
// New creates an instance of the proof of work.
func New() *Ethash {
return &Ethash{new(Light), &Full{turbo: true}}
func New() *Ubqhash {
return &Ubqhash{new(Light), &Full{turbo: true}}
}
// NewShared creates an instance of the proof of work., where a single instance
// of the Light cache is shared across all instances created with NewShared.
func NewShared() *Ethash {
return &Ethash{sharedLight, &Full{turbo: true}}
func NewShared() *Ubqhash {
return &Ubqhash{sharedLight, &Full{turbo: true}}
}
// NewForTesting creates a proof of work for use in unit tests.
@ -417,12 +427,12 @@ func NewShared() *Ethash {
//
// Nonces found by a testing instance are not verifiable with a
// regular-size cache.
func NewForTesting() (*Ethash, error) {
dir, err := ioutil.TempDir("", "ethash-test")
func NewForTesting() (*Ubqhash, error) {
dir, err := ioutil.TempDir("", "ubqhash-test")
if err != nil {
return nil, err
}
return &Ethash{&Light{test: true}, &Full{Dir: dir, test: true}}, nil
return &Ubqhash{&Light{test: true}, &Full{Dir: dir, test: true}}, nil
}
func GetSeedHash(blockNum uint64) ([]byte, error) {

View file

@ -14,7 +14,7 @@
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package ethash
package ubqhash
/*
-mno-stack-arg-probe disables stack probing which avoids the function
@ -32,20 +32,21 @@ package ethash
#cgo windows CFLAGS: -mno-stack-arg-probe
#cgo LDFLAGS: -lm
#include "src/libethash/internal.c"
#include "src/libethash/sha3.c"
#include "src/libethash/io.c"
#include "src/libubqhash/internal.c"
#include "src/libubqhash/sha3.c"
#include "src/libubqhash/blake2b-ref.c"
#include "src/libubqhash/io.c"
#ifdef _WIN32
# include "src/libethash/io_win32.c"
# include "src/libethash/mmap_win32.c"
# include "src/libubqhash/io_win32.c"
# include "src/libubqhash/mmap_win32.c"
#else
# include "src/libethash/io_posix.c"
# include "src/libubqhash/io_posix.c"
#endif
// 'gateway function' for calling back into go.
extern int ethashGoCallback(unsigned);
int ethashGoCallback_cgo(unsigned percent) { return ethashGoCallback(percent); }
extern int ubqhashGoCallback(unsigned);
int ubqhashGoCallback_cgo(unsigned percent) { return ubqhashGoCallback(percent); }
*/
import "C"

244
vendor/golang.org/x/crypto/blake2s/blake2s.go generated vendored Normal file
View file

@ -0,0 +1,244 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package blake2s implements the BLAKE2s hash algorithm defined by RFC 7693
// and the extendable output function (XOF) BLAKE2Xs.
//
// For a detailed specification of BLAKE2s see https://blake2.net/blake2.pdf
// and for BLAKE2Xs see https://blake2.net/blake2x.pdf
//
// If you aren't sure which function you need, use BLAKE2s (Sum256 or New256).
// If you need a secret-key MAC (message authentication code), use the New256
// function with a non-nil key.
//
// BLAKE2X is a construction to compute hash values larger than 32 bytes. It
// can produce hash values between 0 and 65535 bytes.
package blake2s // import "golang.org/x/crypto/blake2s"
import (
"encoding/binary"
"errors"
"hash"
)
const (
// The blocksize of BLAKE2s in bytes.
BlockSize = 64
// The hash size of BLAKE2s-256 in bytes.
Size = 32
// The hash size of BLAKE2s-128 in bytes.
Size128 = 16
)
var errKeySize = errors.New("blake2s: invalid key size")
var iv = [8]uint32{
0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19,
}
// Sum256 returns the BLAKE2s-256 checksum of the data.
func Sum256(data []byte) [Size]byte {
var sum [Size]byte
checkSum(&sum, Size, data)
return sum
}
// New256 returns a new hash.Hash computing the BLAKE2s-256 checksum. A non-nil
// key turns the hash into a MAC. The key must between zero and 32 bytes long.
// When the key is nil, the returned hash.Hash implements BinaryMarshaler
// and BinaryUnmarshaler for state (de)serialization as documented by hash.Hash.
func New256(key []byte) (hash.Hash, error) { return newDigest(Size, key) }
// New128 returns a new hash.Hash computing the BLAKE2s-128 checksum given a
// non-empty key. Note that a 128-bit digest is too small to be secure as a
// cryptographic hash and should only be used as a MAC, thus the key argument
// is not optional.
func New128(key []byte) (hash.Hash, error) {
if len(key) == 0 {
return nil, errors.New("blake2s: a key is required for a 128-bit hash")
}
return newDigest(Size128, key)
}
func newDigest(hashSize int, key []byte) (*digest, error) {
if len(key) > Size {
return nil, errKeySize
}
d := &digest{
size: hashSize,
keyLen: len(key),
}
copy(d.key[:], key)
d.Reset()
return d, nil
}
func checkSum(sum *[Size]byte, hashSize int, data []byte) {
var (
h [8]uint32
c [2]uint32
)
h = iv
h[0] ^= uint32(hashSize) | (1 << 16) | (1 << 24)
if length := len(data); length > BlockSize {
n := length &^ (BlockSize - 1)
if length == n {
n -= BlockSize
}
hashBlocks(&h, &c, 0, data[:n])
data = data[n:]
}
var block [BlockSize]byte
offset := copy(block[:], data)
remaining := uint32(BlockSize - offset)
if c[0] < remaining {
c[1]--
}
c[0] -= remaining
hashBlocks(&h, &c, 0xFFFFFFFF, block[:])
for i, v := range h {
binary.LittleEndian.PutUint32(sum[4*i:], v)
}
}
type digest struct {
h [8]uint32
c [2]uint32
size int
block [BlockSize]byte
offset int
key [BlockSize]byte
keyLen int
}
const (
magic = "b2s"
marshaledSize = len(magic) + 8*4 + 2*4 + 1 + BlockSize + 1
)
func (d *digest) MarshalBinary() ([]byte, error) {
if d.keyLen != 0 {
return nil, errors.New("crypto/blake2s: cannot marshal MACs")
}
b := make([]byte, 0, marshaledSize)
b = append(b, magic...)
for i := 0; i < 8; i++ {
b = appendUint32(b, d.h[i])
}
b = appendUint32(b, d.c[0])
b = appendUint32(b, d.c[1])
// Maximum value for size is 32
b = append(b, byte(d.size))
b = append(b, d.block[:]...)
b = append(b, byte(d.offset))
return b, nil
}
func (d *digest) UnmarshalBinary(b []byte) error {
if len(b) < len(magic) || string(b[:len(magic)]) != magic {
return errors.New("crypto/blake2s: invalid hash state identifier")
}
if len(b) != marshaledSize {
return errors.New("crypto/blake2s: invalid hash state size")
}
b = b[len(magic):]
for i := 0; i < 8; i++ {
b, d.h[i] = consumeUint32(b)
}
b, d.c[0] = consumeUint32(b)
b, d.c[1] = consumeUint32(b)
d.size = int(b[0])
b = b[1:]
copy(d.block[:], b[:BlockSize])
b = b[BlockSize:]
d.offset = int(b[0])
return nil
}
func (d *digest) BlockSize() int { return BlockSize }
func (d *digest) Size() int { return d.size }
func (d *digest) Reset() {
d.h = iv
d.h[0] ^= uint32(d.size) | (uint32(d.keyLen) << 8) | (1 << 16) | (1 << 24)
d.offset, d.c[0], d.c[1] = 0, 0, 0
if d.keyLen > 0 {
d.block = d.key
d.offset = BlockSize
}
}
func (d *digest) Write(p []byte) (n int, err error) {
n = len(p)
if d.offset > 0 {
remaining := BlockSize - d.offset
if n <= remaining {
d.offset += copy(d.block[d.offset:], p)
return
}
copy(d.block[d.offset:], p[:remaining])
hashBlocks(&d.h, &d.c, 0, d.block[:])
d.offset = 0
p = p[remaining:]
}
if length := len(p); length > BlockSize {
nn := length &^ (BlockSize - 1)
if length == nn {
nn -= BlockSize
}
hashBlocks(&d.h, &d.c, 0, p[:nn])
p = p[nn:]
}
d.offset += copy(d.block[:], p)
return
}
func (d *digest) Sum(sum []byte) []byte {
var hash [Size]byte
d.finalize(&hash)
return append(sum, hash[:d.size]...)
}
func (d *digest) finalize(hash *[Size]byte) {
var block [BlockSize]byte
h := d.h
c := d.c
copy(block[:], d.block[:d.offset])
remaining := uint32(BlockSize - d.offset)
if c[0] < remaining {
c[1]--
}
c[0] -= remaining
hashBlocks(&h, &c, 0xFFFFFFFF, block[:])
for i, v := range h {
binary.LittleEndian.PutUint32(hash[4*i:], v)
}
}
func appendUint32(b []byte, x uint32) []byte {
var a [4]byte
binary.BigEndian.PutUint32(a[:], x)
return append(b, a[:]...)
}
func consumeUint32(b []byte) ([]byte, uint32) {
x := binary.BigEndian.Uint32(b)
return b[4:], x
}

32
vendor/golang.org/x/crypto/blake2s/blake2s_386.go generated vendored Normal file
View file

@ -0,0 +1,32 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build 386,!gccgo,!appengine
package blake2s
import "golang.org/x/sys/cpu"
var (
useSSE4 = false
useSSSE3 = cpu.X86.HasSSSE3
useSSE2 = cpu.X86.HasSSE2
)
//go:noescape
func hashBlocksSSE2(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte)
//go:noescape
func hashBlocksSSSE3(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte)
func hashBlocks(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte) {
switch {
case useSSSE3:
hashBlocksSSSE3(h, c, flag, blocks)
case useSSE2:
hashBlocksSSE2(h, c, flag, blocks)
default:
hashBlocksGeneric(h, c, flag, blocks)
}
}

435
vendor/golang.org/x/crypto/blake2s/blake2s_386.s generated vendored Normal file
View file

@ -0,0 +1,435 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build 386,!gccgo,!appengine
#include "textflag.h"
DATA iv0<>+0x00(SB)/4, $0x6a09e667
DATA iv0<>+0x04(SB)/4, $0xbb67ae85
DATA iv0<>+0x08(SB)/4, $0x3c6ef372
DATA iv0<>+0x0c(SB)/4, $0xa54ff53a
GLOBL iv0<>(SB), (NOPTR+RODATA), $16
DATA iv1<>+0x00(SB)/4, $0x510e527f
DATA iv1<>+0x04(SB)/4, $0x9b05688c
DATA iv1<>+0x08(SB)/4, $0x1f83d9ab
DATA iv1<>+0x0c(SB)/4, $0x5be0cd19
GLOBL iv1<>(SB), (NOPTR+RODATA), $16
DATA rol16<>+0x00(SB)/8, $0x0504070601000302
DATA rol16<>+0x08(SB)/8, $0x0D0C0F0E09080B0A
GLOBL rol16<>(SB), (NOPTR+RODATA), $16
DATA rol8<>+0x00(SB)/8, $0x0407060500030201
DATA rol8<>+0x08(SB)/8, $0x0C0F0E0D080B0A09
GLOBL rol8<>(SB), (NOPTR+RODATA), $16
DATA counter<>+0x00(SB)/8, $0x40
DATA counter<>+0x08(SB)/8, $0x0
GLOBL counter<>(SB), (NOPTR+RODATA), $16
#define ROTL_SSE2(n, t, v) \
MOVO v, t; \
PSLLL $n, t; \
PSRLL $(32-n), v; \
PXOR t, v
#define ROTL_SSSE3(c, v) \
PSHUFB c, v
#define ROUND_SSE2(v0, v1, v2, v3, m0, m1, m2, m3, t) \
PADDL m0, v0; \
PADDL v1, v0; \
PXOR v0, v3; \
ROTL_SSE2(16, t, v3); \
PADDL v3, v2; \
PXOR v2, v1; \
ROTL_SSE2(20, t, v1); \
PADDL m1, v0; \
PADDL v1, v0; \
PXOR v0, v3; \
ROTL_SSE2(24, t, v3); \
PADDL v3, v2; \
PXOR v2, v1; \
ROTL_SSE2(25, t, v1); \
PSHUFL $0x39, v1, v1; \
PSHUFL $0x4E, v2, v2; \
PSHUFL $0x93, v3, v3; \
PADDL m2, v0; \
PADDL v1, v0; \
PXOR v0, v3; \
ROTL_SSE2(16, t, v3); \
PADDL v3, v2; \
PXOR v2, v1; \
ROTL_SSE2(20, t, v1); \
PADDL m3, v0; \
PADDL v1, v0; \
PXOR v0, v3; \
ROTL_SSE2(24, t, v3); \
PADDL v3, v2; \
PXOR v2, v1; \
ROTL_SSE2(25, t, v1); \
PSHUFL $0x39, v3, v3; \
PSHUFL $0x4E, v2, v2; \
PSHUFL $0x93, v1, v1
#define ROUND_SSSE3(v0, v1, v2, v3, m0, m1, m2, m3, t, c16, c8) \
PADDL m0, v0; \
PADDL v1, v0; \
PXOR v0, v3; \
ROTL_SSSE3(c16, v3); \
PADDL v3, v2; \
PXOR v2, v1; \
ROTL_SSE2(20, t, v1); \
PADDL m1, v0; \
PADDL v1, v0; \
PXOR v0, v3; \
ROTL_SSSE3(c8, v3); \
PADDL v3, v2; \
PXOR v2, v1; \
ROTL_SSE2(25, t, v1); \
PSHUFL $0x39, v1, v1; \
PSHUFL $0x4E, v2, v2; \
PSHUFL $0x93, v3, v3; \
PADDL m2, v0; \
PADDL v1, v0; \
PXOR v0, v3; \
ROTL_SSSE3(c16, v3); \
PADDL v3, v2; \
PXOR v2, v1; \
ROTL_SSE2(20, t, v1); \
PADDL m3, v0; \
PADDL v1, v0; \
PXOR v0, v3; \
ROTL_SSSE3(c8, v3); \
PADDL v3, v2; \
PXOR v2, v1; \
ROTL_SSE2(25, t, v1); \
PSHUFL $0x39, v3, v3; \
PSHUFL $0x4E, v2, v2; \
PSHUFL $0x93, v1, v1
#define PRECOMPUTE(dst, off, src, t) \
MOVL 0*4(src), t; \
MOVL t, 0*4+off+0(dst); \
MOVL t, 9*4+off+64(dst); \
MOVL t, 5*4+off+128(dst); \
MOVL t, 14*4+off+192(dst); \
MOVL t, 4*4+off+256(dst); \
MOVL t, 2*4+off+320(dst); \
MOVL t, 8*4+off+384(dst); \
MOVL t, 12*4+off+448(dst); \
MOVL t, 3*4+off+512(dst); \
MOVL t, 15*4+off+576(dst); \
MOVL 1*4(src), t; \
MOVL t, 4*4+off+0(dst); \
MOVL t, 8*4+off+64(dst); \
MOVL t, 14*4+off+128(dst); \
MOVL t, 5*4+off+192(dst); \
MOVL t, 12*4+off+256(dst); \
MOVL t, 11*4+off+320(dst); \
MOVL t, 1*4+off+384(dst); \
MOVL t, 6*4+off+448(dst); \
MOVL t, 10*4+off+512(dst); \
MOVL t, 3*4+off+576(dst); \
MOVL 2*4(src), t; \
MOVL t, 1*4+off+0(dst); \
MOVL t, 13*4+off+64(dst); \
MOVL t, 6*4+off+128(dst); \
MOVL t, 8*4+off+192(dst); \
MOVL t, 2*4+off+256(dst); \
MOVL t, 0*4+off+320(dst); \
MOVL t, 14*4+off+384(dst); \
MOVL t, 11*4+off+448(dst); \
MOVL t, 12*4+off+512(dst); \
MOVL t, 4*4+off+576(dst); \
MOVL 3*4(src), t; \
MOVL t, 5*4+off+0(dst); \
MOVL t, 15*4+off+64(dst); \
MOVL t, 9*4+off+128(dst); \
MOVL t, 1*4+off+192(dst); \
MOVL t, 11*4+off+256(dst); \
MOVL t, 7*4+off+320(dst); \
MOVL t, 13*4+off+384(dst); \
MOVL t, 3*4+off+448(dst); \
MOVL t, 6*4+off+512(dst); \
MOVL t, 10*4+off+576(dst); \
MOVL 4*4(src), t; \
MOVL t, 2*4+off+0(dst); \
MOVL t, 1*4+off+64(dst); \
MOVL t, 15*4+off+128(dst); \
MOVL t, 10*4+off+192(dst); \
MOVL t, 6*4+off+256(dst); \
MOVL t, 8*4+off+320(dst); \
MOVL t, 3*4+off+384(dst); \
MOVL t, 13*4+off+448(dst); \
MOVL t, 14*4+off+512(dst); \
MOVL t, 5*4+off+576(dst); \
MOVL 5*4(src), t; \
MOVL t, 6*4+off+0(dst); \
MOVL t, 11*4+off+64(dst); \
MOVL t, 2*4+off+128(dst); \
MOVL t, 9*4+off+192(dst); \
MOVL t, 1*4+off+256(dst); \
MOVL t, 13*4+off+320(dst); \
MOVL t, 4*4+off+384(dst); \
MOVL t, 8*4+off+448(dst); \
MOVL t, 15*4+off+512(dst); \
MOVL t, 7*4+off+576(dst); \
MOVL 6*4(src), t; \
MOVL t, 3*4+off+0(dst); \
MOVL t, 7*4+off+64(dst); \
MOVL t, 13*4+off+128(dst); \
MOVL t, 12*4+off+192(dst); \
MOVL t, 10*4+off+256(dst); \
MOVL t, 1*4+off+320(dst); \
MOVL t, 9*4+off+384(dst); \
MOVL t, 14*4+off+448(dst); \
MOVL t, 0*4+off+512(dst); \
MOVL t, 6*4+off+576(dst); \
MOVL 7*4(src), t; \
MOVL t, 7*4+off+0(dst); \
MOVL t, 14*4+off+64(dst); \
MOVL t, 10*4+off+128(dst); \
MOVL t, 0*4+off+192(dst); \
MOVL t, 5*4+off+256(dst); \
MOVL t, 9*4+off+320(dst); \
MOVL t, 12*4+off+384(dst); \
MOVL t, 1*4+off+448(dst); \
MOVL t, 13*4+off+512(dst); \
MOVL t, 2*4+off+576(dst); \
MOVL 8*4(src), t; \
MOVL t, 8*4+off+0(dst); \
MOVL t, 5*4+off+64(dst); \
MOVL t, 4*4+off+128(dst); \
MOVL t, 15*4+off+192(dst); \
MOVL t, 14*4+off+256(dst); \
MOVL t, 3*4+off+320(dst); \
MOVL t, 11*4+off+384(dst); \
MOVL t, 10*4+off+448(dst); \
MOVL t, 7*4+off+512(dst); \
MOVL t, 1*4+off+576(dst); \
MOVL 9*4(src), t; \
MOVL t, 12*4+off+0(dst); \
MOVL t, 2*4+off+64(dst); \
MOVL t, 11*4+off+128(dst); \
MOVL t, 4*4+off+192(dst); \
MOVL t, 0*4+off+256(dst); \
MOVL t, 15*4+off+320(dst); \
MOVL t, 10*4+off+384(dst); \
MOVL t, 7*4+off+448(dst); \
MOVL t, 5*4+off+512(dst); \
MOVL t, 9*4+off+576(dst); \
MOVL 10*4(src), t; \
MOVL t, 9*4+off+0(dst); \
MOVL t, 4*4+off+64(dst); \
MOVL t, 8*4+off+128(dst); \
MOVL t, 13*4+off+192(dst); \
MOVL t, 3*4+off+256(dst); \
MOVL t, 5*4+off+320(dst); \
MOVL t, 7*4+off+384(dst); \
MOVL t, 15*4+off+448(dst); \
MOVL t, 11*4+off+512(dst); \
MOVL t, 0*4+off+576(dst); \
MOVL 11*4(src), t; \
MOVL t, 13*4+off+0(dst); \
MOVL t, 10*4+off+64(dst); \
MOVL t, 0*4+off+128(dst); \
MOVL t, 3*4+off+192(dst); \
MOVL t, 9*4+off+256(dst); \
MOVL t, 6*4+off+320(dst); \
MOVL t, 15*4+off+384(dst); \
MOVL t, 4*4+off+448(dst); \
MOVL t, 2*4+off+512(dst); \
MOVL t, 12*4+off+576(dst); \
MOVL 12*4(src), t; \
MOVL t, 10*4+off+0(dst); \
MOVL t, 12*4+off+64(dst); \
MOVL t, 1*4+off+128(dst); \
MOVL t, 6*4+off+192(dst); \
MOVL t, 13*4+off+256(dst); \
MOVL t, 4*4+off+320(dst); \
MOVL t, 0*4+off+384(dst); \
MOVL t, 2*4+off+448(dst); \
MOVL t, 8*4+off+512(dst); \
MOVL t, 14*4+off+576(dst); \
MOVL 13*4(src), t; \
MOVL t, 14*4+off+0(dst); \
MOVL t, 3*4+off+64(dst); \
MOVL t, 7*4+off+128(dst); \
MOVL t, 2*4+off+192(dst); \
MOVL t, 15*4+off+256(dst); \
MOVL t, 12*4+off+320(dst); \
MOVL t, 6*4+off+384(dst); \
MOVL t, 0*4+off+448(dst); \
MOVL t, 9*4+off+512(dst); \
MOVL t, 11*4+off+576(dst); \
MOVL 14*4(src), t; \
MOVL t, 11*4+off+0(dst); \
MOVL t, 0*4+off+64(dst); \
MOVL t, 12*4+off+128(dst); \
MOVL t, 7*4+off+192(dst); \
MOVL t, 8*4+off+256(dst); \
MOVL t, 14*4+off+320(dst); \
MOVL t, 2*4+off+384(dst); \
MOVL t, 5*4+off+448(dst); \
MOVL t, 1*4+off+512(dst); \
MOVL t, 13*4+off+576(dst); \
MOVL 15*4(src), t; \
MOVL t, 15*4+off+0(dst); \
MOVL t, 6*4+off+64(dst); \
MOVL t, 3*4+off+128(dst); \
MOVL t, 11*4+off+192(dst); \
MOVL t, 7*4+off+256(dst); \
MOVL t, 10*4+off+320(dst); \
MOVL t, 5*4+off+384(dst); \
MOVL t, 9*4+off+448(dst); \
MOVL t, 4*4+off+512(dst); \
MOVL t, 8*4+off+576(dst)
// func hashBlocksSSE2(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte)
TEXT ·hashBlocksSSE2(SB), 0, $672-24 // frame = 656 + 16 byte alignment
MOVL h+0(FP), AX
MOVL c+4(FP), BX
MOVL flag+8(FP), CX
MOVL blocks_base+12(FP), SI
MOVL blocks_len+16(FP), DX
MOVL SP, BP
MOVL SP, DI
ADDL $15, DI
ANDL $~15, DI
MOVL DI, SP
MOVL CX, 8(SP)
MOVL 0(BX), CX
MOVL CX, 0(SP)
MOVL 4(BX), CX
MOVL CX, 4(SP)
XORL CX, CX
MOVL CX, 12(SP)
MOVOU 0(AX), X0
MOVOU 16(AX), X1
MOVOU counter<>(SB), X2
loop:
MOVO X0, X4
MOVO X1, X5
MOVOU iv0<>(SB), X6
MOVOU iv1<>(SB), X7
MOVO 0(SP), X3
PADDQ X2, X3
PXOR X3, X7
MOVO X3, 0(SP)
PRECOMPUTE(SP, 16, SI, CX)
ROUND_SSE2(X4, X5, X6, X7, 16(SP), 32(SP), 48(SP), 64(SP), X3)
ROUND_SSE2(X4, X5, X6, X7, 16+64(SP), 32+64(SP), 48+64(SP), 64+64(SP), X3)
ROUND_SSE2(X4, X5, X6, X7, 16+128(SP), 32+128(SP), 48+128(SP), 64+128(SP), X3)
ROUND_SSE2(X4, X5, X6, X7, 16+192(SP), 32+192(SP), 48+192(SP), 64+192(SP), X3)
ROUND_SSE2(X4, X5, X6, X7, 16+256(SP), 32+256(SP), 48+256(SP), 64+256(SP), X3)
ROUND_SSE2(X4, X5, X6, X7, 16+320(SP), 32+320(SP), 48+320(SP), 64+320(SP), X3)
ROUND_SSE2(X4, X5, X6, X7, 16+384(SP), 32+384(SP), 48+384(SP), 64+384(SP), X3)
ROUND_SSE2(X4, X5, X6, X7, 16+448(SP), 32+448(SP), 48+448(SP), 64+448(SP), X3)
ROUND_SSE2(X4, X5, X6, X7, 16+512(SP), 32+512(SP), 48+512(SP), 64+512(SP), X3)
ROUND_SSE2(X4, X5, X6, X7, 16+576(SP), 32+576(SP), 48+576(SP), 64+576(SP), X3)
PXOR X4, X0
PXOR X5, X1
PXOR X6, X0
PXOR X7, X1
LEAL 64(SI), SI
SUBL $64, DX
JNE loop
MOVL 0(SP), CX
MOVL CX, 0(BX)
MOVL 4(SP), CX
MOVL CX, 4(BX)
MOVOU X0, 0(AX)
MOVOU X1, 16(AX)
MOVL BP, SP
RET
// func hashBlocksSSSE3(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte)
TEXT ·hashBlocksSSSE3(SB), 0, $704-24 // frame = 688 + 16 byte alignment
MOVL h+0(FP), AX
MOVL c+4(FP), BX
MOVL flag+8(FP), CX
MOVL blocks_base+12(FP), SI
MOVL blocks_len+16(FP), DX
MOVL SP, BP
MOVL SP, DI
ADDL $15, DI
ANDL $~15, DI
MOVL DI, SP
MOVL CX, 8(SP)
MOVL 0(BX), CX
MOVL CX, 0(SP)
MOVL 4(BX), CX
MOVL CX, 4(SP)
XORL CX, CX
MOVL CX, 12(SP)
MOVOU 0(AX), X0
MOVOU 16(AX), X1
MOVOU counter<>(SB), X2
loop:
MOVO X0, 656(SP)
MOVO X1, 672(SP)
MOVO X0, X4
MOVO X1, X5
MOVOU iv0<>(SB), X6
MOVOU iv1<>(SB), X7
MOVO 0(SP), X3
PADDQ X2, X3
PXOR X3, X7
MOVO X3, 0(SP)
MOVOU rol16<>(SB), X0
MOVOU rol8<>(SB), X1
PRECOMPUTE(SP, 16, SI, CX)
ROUND_SSSE3(X4, X5, X6, X7, 16(SP), 32(SP), 48(SP), 64(SP), X3, X0, X1)
ROUND_SSSE3(X4, X5, X6, X7, 16+64(SP), 32+64(SP), 48+64(SP), 64+64(SP), X3, X0, X1)
ROUND_SSSE3(X4, X5, X6, X7, 16+128(SP), 32+128(SP), 48+128(SP), 64+128(SP), X3, X0, X1)
ROUND_SSSE3(X4, X5, X6, X7, 16+192(SP), 32+192(SP), 48+192(SP), 64+192(SP), X3, X0, X1)
ROUND_SSSE3(X4, X5, X6, X7, 16+256(SP), 32+256(SP), 48+256(SP), 64+256(SP), X3, X0, X1)
ROUND_SSSE3(X4, X5, X6, X7, 16+320(SP), 32+320(SP), 48+320(SP), 64+320(SP), X3, X0, X1)
ROUND_SSSE3(X4, X5, X6, X7, 16+384(SP), 32+384(SP), 48+384(SP), 64+384(SP), X3, X0, X1)
ROUND_SSSE3(X4, X5, X6, X7, 16+448(SP), 32+448(SP), 48+448(SP), 64+448(SP), X3, X0, X1)
ROUND_SSSE3(X4, X5, X6, X7, 16+512(SP), 32+512(SP), 48+512(SP), 64+512(SP), X3, X0, X1)
ROUND_SSSE3(X4, X5, X6, X7, 16+576(SP), 32+576(SP), 48+576(SP), 64+576(SP), X3, X0, X1)
MOVO 656(SP), X0
MOVO 672(SP), X1
PXOR X4, X0
PXOR X5, X1
PXOR X6, X0
PXOR X7, X1
LEAL 64(SI), SI
SUBL $64, DX
JNE loop
MOVL 0(SP), CX
MOVL CX, 0(BX)
MOVL 4(SP), CX
MOVL CX, 4(BX)
MOVOU X0, 0(AX)
MOVOU X1, 16(AX)
MOVL BP, SP
RET

37
vendor/golang.org/x/crypto/blake2s/blake2s_amd64.go generated vendored Normal file
View file

@ -0,0 +1,37 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build amd64,!gccgo,!appengine
package blake2s
import "golang.org/x/sys/cpu"
var (
useSSE4 = cpu.X86.HasSSE41
useSSSE3 = cpu.X86.HasSSSE3
useSSE2 = cpu.X86.HasSSE2
)
//go:noescape
func hashBlocksSSE2(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte)
//go:noescape
func hashBlocksSSSE3(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte)
//go:noescape
func hashBlocksSSE4(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte)
func hashBlocks(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte) {
switch {
case useSSE4:
hashBlocksSSE4(h, c, flag, blocks)
case useSSSE3:
hashBlocksSSSE3(h, c, flag, blocks)
case useSSE2:
hashBlocksSSE2(h, c, flag, blocks)
default:
hashBlocksGeneric(h, c, flag, blocks)
}
}

438
vendor/golang.org/x/crypto/blake2s/blake2s_amd64.s generated vendored Normal file
View file

@ -0,0 +1,438 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build amd64,!gccgo,!appengine
#include "textflag.h"
DATA iv0<>+0x00(SB)/4, $0x6a09e667
DATA iv0<>+0x04(SB)/4, $0xbb67ae85
DATA iv0<>+0x08(SB)/4, $0x3c6ef372
DATA iv0<>+0x0c(SB)/4, $0xa54ff53a
GLOBL iv0<>(SB), (NOPTR+RODATA), $16
DATA iv1<>+0x00(SB)/4, $0x510e527f
DATA iv1<>+0x04(SB)/4, $0x9b05688c
DATA iv1<>+0x08(SB)/4, $0x1f83d9ab
DATA iv1<>+0x0c(SB)/4, $0x5be0cd19
GLOBL iv1<>(SB), (NOPTR+RODATA), $16
DATA rol16<>+0x00(SB)/8, $0x0504070601000302
DATA rol16<>+0x08(SB)/8, $0x0D0C0F0E09080B0A
GLOBL rol16<>(SB), (NOPTR+RODATA), $16
DATA rol8<>+0x00(SB)/8, $0x0407060500030201
DATA rol8<>+0x08(SB)/8, $0x0C0F0E0D080B0A09
GLOBL rol8<>(SB), (NOPTR+RODATA), $16
DATA counter<>+0x00(SB)/8, $0x40
DATA counter<>+0x08(SB)/8, $0x0
GLOBL counter<>(SB), (NOPTR+RODATA), $16
#define ROTL_SSE2(n, t, v) \
MOVO v, t; \
PSLLL $n, t; \
PSRLL $(32-n), v; \
PXOR t, v
#define ROTL_SSSE3(c, v) \
PSHUFB c, v
#define ROUND_SSE2(v0, v1, v2, v3, m0, m1, m2, m3, t) \
PADDL m0, v0; \
PADDL v1, v0; \
PXOR v0, v3; \
ROTL_SSE2(16, t, v3); \
PADDL v3, v2; \
PXOR v2, v1; \
ROTL_SSE2(20, t, v1); \
PADDL m1, v0; \
PADDL v1, v0; \
PXOR v0, v3; \
ROTL_SSE2(24, t, v3); \
PADDL v3, v2; \
PXOR v2, v1; \
ROTL_SSE2(25, t, v1); \
PSHUFL $0x39, v1, v1; \
PSHUFL $0x4E, v2, v2; \
PSHUFL $0x93, v3, v3; \
PADDL m2, v0; \
PADDL v1, v0; \
PXOR v0, v3; \
ROTL_SSE2(16, t, v3); \
PADDL v3, v2; \
PXOR v2, v1; \
ROTL_SSE2(20, t, v1); \
PADDL m3, v0; \
PADDL v1, v0; \
PXOR v0, v3; \
ROTL_SSE2(24, t, v3); \
PADDL v3, v2; \
PXOR v2, v1; \
ROTL_SSE2(25, t, v1); \
PSHUFL $0x39, v3, v3; \
PSHUFL $0x4E, v2, v2; \
PSHUFL $0x93, v1, v1
#define ROUND_SSSE3(v0, v1, v2, v3, m0, m1, m2, m3, t, c16, c8) \
PADDL m0, v0; \
PADDL v1, v0; \
PXOR v0, v3; \
ROTL_SSSE3(c16, v3); \
PADDL v3, v2; \
PXOR v2, v1; \
ROTL_SSE2(20, t, v1); \
PADDL m1, v0; \
PADDL v1, v0; \
PXOR v0, v3; \
ROTL_SSSE3(c8, v3); \
PADDL v3, v2; \
PXOR v2, v1; \
ROTL_SSE2(25, t, v1); \
PSHUFL $0x39, v1, v1; \
PSHUFL $0x4E, v2, v2; \
PSHUFL $0x93, v3, v3; \
PADDL m2, v0; \
PADDL v1, v0; \
PXOR v0, v3; \
ROTL_SSSE3(c16, v3); \
PADDL v3, v2; \
PXOR v2, v1; \
ROTL_SSE2(20, t, v1); \
PADDL m3, v0; \
PADDL v1, v0; \
PXOR v0, v3; \
ROTL_SSSE3(c8, v3); \
PADDL v3, v2; \
PXOR v2, v1; \
ROTL_SSE2(25, t, v1); \
PSHUFL $0x39, v3, v3; \
PSHUFL $0x4E, v2, v2; \
PSHUFL $0x93, v1, v1
#define LOAD_MSG_SSE4(m0, m1, m2, m3, src, i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14, i15) \
MOVL i0*4(src), m0; \
PINSRD $1, i1*4(src), m0; \
PINSRD $2, i2*4(src), m0; \
PINSRD $3, i3*4(src), m0; \
MOVL i4*4(src), m1; \
PINSRD $1, i5*4(src), m1; \
PINSRD $2, i6*4(src), m1; \
PINSRD $3, i7*4(src), m1; \
MOVL i8*4(src), m2; \
PINSRD $1, i9*4(src), m2; \
PINSRD $2, i10*4(src), m2; \
PINSRD $3, i11*4(src), m2; \
MOVL i12*4(src), m3; \
PINSRD $1, i13*4(src), m3; \
PINSRD $2, i14*4(src), m3; \
PINSRD $3, i15*4(src), m3
#define PRECOMPUTE_MSG(dst, off, src, R8, R9, R10, R11, R12, R13, R14, R15) \
MOVQ 0*4(src), R8; \
MOVQ 2*4(src), R9; \
MOVQ 4*4(src), R10; \
MOVQ 6*4(src), R11; \
MOVQ 8*4(src), R12; \
MOVQ 10*4(src), R13; \
MOVQ 12*4(src), R14; \
MOVQ 14*4(src), R15; \
\
MOVL R8, 0*4+off+0(dst); \
MOVL R8, 9*4+off+64(dst); \
MOVL R8, 5*4+off+128(dst); \
MOVL R8, 14*4+off+192(dst); \
MOVL R8, 4*4+off+256(dst); \
MOVL R8, 2*4+off+320(dst); \
MOVL R8, 8*4+off+384(dst); \
MOVL R8, 12*4+off+448(dst); \
MOVL R8, 3*4+off+512(dst); \
MOVL R8, 15*4+off+576(dst); \
SHRQ $32, R8; \
MOVL R8, 4*4+off+0(dst); \
MOVL R8, 8*4+off+64(dst); \
MOVL R8, 14*4+off+128(dst); \
MOVL R8, 5*4+off+192(dst); \
MOVL R8, 12*4+off+256(dst); \
MOVL R8, 11*4+off+320(dst); \
MOVL R8, 1*4+off+384(dst); \
MOVL R8, 6*4+off+448(dst); \
MOVL R8, 10*4+off+512(dst); \
MOVL R8, 3*4+off+576(dst); \
\
MOVL R9, 1*4+off+0(dst); \
MOVL R9, 13*4+off+64(dst); \
MOVL R9, 6*4+off+128(dst); \
MOVL R9, 8*4+off+192(dst); \
MOVL R9, 2*4+off+256(dst); \
MOVL R9, 0*4+off+320(dst); \
MOVL R9, 14*4+off+384(dst); \
MOVL R9, 11*4+off+448(dst); \
MOVL R9, 12*4+off+512(dst); \
MOVL R9, 4*4+off+576(dst); \
SHRQ $32, R9; \
MOVL R9, 5*4+off+0(dst); \
MOVL R9, 15*4+off+64(dst); \
MOVL R9, 9*4+off+128(dst); \
MOVL R9, 1*4+off+192(dst); \
MOVL R9, 11*4+off+256(dst); \
MOVL R9, 7*4+off+320(dst); \
MOVL R9, 13*4+off+384(dst); \
MOVL R9, 3*4+off+448(dst); \
MOVL R9, 6*4+off+512(dst); \
MOVL R9, 10*4+off+576(dst); \
\
MOVL R10, 2*4+off+0(dst); \
MOVL R10, 1*4+off+64(dst); \
MOVL R10, 15*4+off+128(dst); \
MOVL R10, 10*4+off+192(dst); \
MOVL R10, 6*4+off+256(dst); \
MOVL R10, 8*4+off+320(dst); \
MOVL R10, 3*4+off+384(dst); \
MOVL R10, 13*4+off+448(dst); \
MOVL R10, 14*4+off+512(dst); \
MOVL R10, 5*4+off+576(dst); \
SHRQ $32, R10; \
MOVL R10, 6*4+off+0(dst); \
MOVL R10, 11*4+off+64(dst); \
MOVL R10, 2*4+off+128(dst); \
MOVL R10, 9*4+off+192(dst); \
MOVL R10, 1*4+off+256(dst); \
MOVL R10, 13*4+off+320(dst); \
MOVL R10, 4*4+off+384(dst); \
MOVL R10, 8*4+off+448(dst); \
MOVL R10, 15*4+off+512(dst); \
MOVL R10, 7*4+off+576(dst); \
\
MOVL R11, 3*4+off+0(dst); \
MOVL R11, 7*4+off+64(dst); \
MOVL R11, 13*4+off+128(dst); \
MOVL R11, 12*4+off+192(dst); \
MOVL R11, 10*4+off+256(dst); \
MOVL R11, 1*4+off+320(dst); \
MOVL R11, 9*4+off+384(dst); \
MOVL R11, 14*4+off+448(dst); \
MOVL R11, 0*4+off+512(dst); \
MOVL R11, 6*4+off+576(dst); \
SHRQ $32, R11; \
MOVL R11, 7*4+off+0(dst); \
MOVL R11, 14*4+off+64(dst); \
MOVL R11, 10*4+off+128(dst); \
MOVL R11, 0*4+off+192(dst); \
MOVL R11, 5*4+off+256(dst); \
MOVL R11, 9*4+off+320(dst); \
MOVL R11, 12*4+off+384(dst); \
MOVL R11, 1*4+off+448(dst); \
MOVL R11, 13*4+off+512(dst); \
MOVL R11, 2*4+off+576(dst); \
\
MOVL R12, 8*4+off+0(dst); \
MOVL R12, 5*4+off+64(dst); \
MOVL R12, 4*4+off+128(dst); \
MOVL R12, 15*4+off+192(dst); \
MOVL R12, 14*4+off+256(dst); \
MOVL R12, 3*4+off+320(dst); \
MOVL R12, 11*4+off+384(dst); \
MOVL R12, 10*4+off+448(dst); \
MOVL R12, 7*4+off+512(dst); \
MOVL R12, 1*4+off+576(dst); \
SHRQ $32, R12; \
MOVL R12, 12*4+off+0(dst); \
MOVL R12, 2*4+off+64(dst); \
MOVL R12, 11*4+off+128(dst); \
MOVL R12, 4*4+off+192(dst); \
MOVL R12, 0*4+off+256(dst); \
MOVL R12, 15*4+off+320(dst); \
MOVL R12, 10*4+off+384(dst); \
MOVL R12, 7*4+off+448(dst); \
MOVL R12, 5*4+off+512(dst); \
MOVL R12, 9*4+off+576(dst); \
\
MOVL R13, 9*4+off+0(dst); \
MOVL R13, 4*4+off+64(dst); \
MOVL R13, 8*4+off+128(dst); \
MOVL R13, 13*4+off+192(dst); \
MOVL R13, 3*4+off+256(dst); \
MOVL R13, 5*4+off+320(dst); \
MOVL R13, 7*4+off+384(dst); \
MOVL R13, 15*4+off+448(dst); \
MOVL R13, 11*4+off+512(dst); \
MOVL R13, 0*4+off+576(dst); \
SHRQ $32, R13; \
MOVL R13, 13*4+off+0(dst); \
MOVL R13, 10*4+off+64(dst); \
MOVL R13, 0*4+off+128(dst); \
MOVL R13, 3*4+off+192(dst); \
MOVL R13, 9*4+off+256(dst); \
MOVL R13, 6*4+off+320(dst); \
MOVL R13, 15*4+off+384(dst); \
MOVL R13, 4*4+off+448(dst); \
MOVL R13, 2*4+off+512(dst); \
MOVL R13, 12*4+off+576(dst); \
\
MOVL R14, 10*4+off+0(dst); \
MOVL R14, 12*4+off+64(dst); \
MOVL R14, 1*4+off+128(dst); \
MOVL R14, 6*4+off+192(dst); \
MOVL R14, 13*4+off+256(dst); \
MOVL R14, 4*4+off+320(dst); \
MOVL R14, 0*4+off+384(dst); \
MOVL R14, 2*4+off+448(dst); \
MOVL R14, 8*4+off+512(dst); \
MOVL R14, 14*4+off+576(dst); \
SHRQ $32, R14; \
MOVL R14, 14*4+off+0(dst); \
MOVL R14, 3*4+off+64(dst); \
MOVL R14, 7*4+off+128(dst); \
MOVL R14, 2*4+off+192(dst); \
MOVL R14, 15*4+off+256(dst); \
MOVL R14, 12*4+off+320(dst); \
MOVL R14, 6*4+off+384(dst); \
MOVL R14, 0*4+off+448(dst); \
MOVL R14, 9*4+off+512(dst); \
MOVL R14, 11*4+off+576(dst); \
\
MOVL R15, 11*4+off+0(dst); \
MOVL R15, 0*4+off+64(dst); \
MOVL R15, 12*4+off+128(dst); \
MOVL R15, 7*4+off+192(dst); \
MOVL R15, 8*4+off+256(dst); \
MOVL R15, 14*4+off+320(dst); \
MOVL R15, 2*4+off+384(dst); \
MOVL R15, 5*4+off+448(dst); \
MOVL R15, 1*4+off+512(dst); \
MOVL R15, 13*4+off+576(dst); \
SHRQ $32, R15; \
MOVL R15, 15*4+off+0(dst); \
MOVL R15, 6*4+off+64(dst); \
MOVL R15, 3*4+off+128(dst); \
MOVL R15, 11*4+off+192(dst); \
MOVL R15, 7*4+off+256(dst); \
MOVL R15, 10*4+off+320(dst); \
MOVL R15, 5*4+off+384(dst); \
MOVL R15, 9*4+off+448(dst); \
MOVL R15, 4*4+off+512(dst); \
MOVL R15, 8*4+off+576(dst)
#define BLAKE2s_SSE2() \
PRECOMPUTE_MSG(SP, 16, SI, R8, R9, R10, R11, R12, R13, R14, R15); \
ROUND_SSE2(X4, X5, X6, X7, 16(SP), 32(SP), 48(SP), 64(SP), X8); \
ROUND_SSE2(X4, X5, X6, X7, 16+64(SP), 32+64(SP), 48+64(SP), 64+64(SP), X8); \
ROUND_SSE2(X4, X5, X6, X7, 16+128(SP), 32+128(SP), 48+128(SP), 64+128(SP), X8); \
ROUND_SSE2(X4, X5, X6, X7, 16+192(SP), 32+192(SP), 48+192(SP), 64+192(SP), X8); \
ROUND_SSE2(X4, X5, X6, X7, 16+256(SP), 32+256(SP), 48+256(SP), 64+256(SP), X8); \
ROUND_SSE2(X4, X5, X6, X7, 16+320(SP), 32+320(SP), 48+320(SP), 64+320(SP), X8); \
ROUND_SSE2(X4, X5, X6, X7, 16+384(SP), 32+384(SP), 48+384(SP), 64+384(SP), X8); \
ROUND_SSE2(X4, X5, X6, X7, 16+448(SP), 32+448(SP), 48+448(SP), 64+448(SP), X8); \
ROUND_SSE2(X4, X5, X6, X7, 16+512(SP), 32+512(SP), 48+512(SP), 64+512(SP), X8); \
ROUND_SSE2(X4, X5, X6, X7, 16+576(SP), 32+576(SP), 48+576(SP), 64+576(SP), X8)
#define BLAKE2s_SSSE3() \
PRECOMPUTE_MSG(SP, 16, SI, R8, R9, R10, R11, R12, R13, R14, R15); \
ROUND_SSSE3(X4, X5, X6, X7, 16(SP), 32(SP), 48(SP), 64(SP), X8, X13, X14); \
ROUND_SSSE3(X4, X5, X6, X7, 16+64(SP), 32+64(SP), 48+64(SP), 64+64(SP), X8, X13, X14); \
ROUND_SSSE3(X4, X5, X6, X7, 16+128(SP), 32+128(SP), 48+128(SP), 64+128(SP), X8, X13, X14); \
ROUND_SSSE3(X4, X5, X6, X7, 16+192(SP), 32+192(SP), 48+192(SP), 64+192(SP), X8, X13, X14); \
ROUND_SSSE3(X4, X5, X6, X7, 16+256(SP), 32+256(SP), 48+256(SP), 64+256(SP), X8, X13, X14); \
ROUND_SSSE3(X4, X5, X6, X7, 16+320(SP), 32+320(SP), 48+320(SP), 64+320(SP), X8, X13, X14); \
ROUND_SSSE3(X4, X5, X6, X7, 16+384(SP), 32+384(SP), 48+384(SP), 64+384(SP), X8, X13, X14); \
ROUND_SSSE3(X4, X5, X6, X7, 16+448(SP), 32+448(SP), 48+448(SP), 64+448(SP), X8, X13, X14); \
ROUND_SSSE3(X4, X5, X6, X7, 16+512(SP), 32+512(SP), 48+512(SP), 64+512(SP), X8, X13, X14); \
ROUND_SSSE3(X4, X5, X6, X7, 16+576(SP), 32+576(SP), 48+576(SP), 64+576(SP), X8, X13, X14)
#define BLAKE2s_SSE4() \
LOAD_MSG_SSE4(X8, X9, X10, X11, SI, 0, 2, 4, 6, 1, 3, 5, 7, 8, 10, 12, 14, 9, 11, 13, 15); \
ROUND_SSSE3(X4, X5, X6, X7, X8, X9, X10, X11, X8, X13, X14); \
LOAD_MSG_SSE4(X8, X9, X10, X11, SI, 14, 4, 9, 13, 10, 8, 15, 6, 1, 0, 11, 5, 12, 2, 7, 3); \
ROUND_SSSE3(X4, X5, X6, X7, X8, X9, X10, X11, X8, X13, X14); \
LOAD_MSG_SSE4(X8, X9, X10, X11, SI, 11, 12, 5, 15, 8, 0, 2, 13, 10, 3, 7, 9, 14, 6, 1, 4); \
ROUND_SSSE3(X4, X5, X6, X7, X8, X9, X10, X11, X8, X13, X14); \
LOAD_MSG_SSE4(X8, X9, X10, X11, SI, 7, 3, 13, 11, 9, 1, 12, 14, 2, 5, 4, 15, 6, 10, 0, 8); \
ROUND_SSSE3(X4, X5, X6, X7, X8, X9, X10, X11, X8, X13, X14); \
LOAD_MSG_SSE4(X8, X9, X10, X11, SI, 9, 5, 2, 10, 0, 7, 4, 15, 14, 11, 6, 3, 1, 12, 8, 13); \
ROUND_SSSE3(X4, X5, X6, X7, X8, X9, X10, X11, X8, X13, X14); \
LOAD_MSG_SSE4(X8, X9, X10, X11, SI, 2, 6, 0, 8, 12, 10, 11, 3, 4, 7, 15, 1, 13, 5, 14, 9); \
ROUND_SSSE3(X4, X5, X6, X7, X8, X9, X10, X11, X8, X13, X14); \
LOAD_MSG_SSE4(X8, X9, X10, X11, SI, 12, 1, 14, 4, 5, 15, 13, 10, 0, 6, 9, 8, 7, 3, 2, 11); \
ROUND_SSSE3(X4, X5, X6, X7, X8, X9, X10, X11, X8, X13, X14); \
LOAD_MSG_SSE4(X8, X9, X10, X11, SI, 13, 7, 12, 3, 11, 14, 1, 9, 5, 15, 8, 2, 0, 4, 6, 10); \
ROUND_SSSE3(X4, X5, X6, X7, X8, X9, X10, X11, X8, X13, X14); \
LOAD_MSG_SSE4(X8, X9, X10, X11, SI, 6, 14, 11, 0, 15, 9, 3, 8, 12, 13, 1, 10, 2, 7, 4, 5); \
ROUND_SSSE3(X4, X5, X6, X7, X8, X9, X10, X11, X8, X13, X14); \
LOAD_MSG_SSE4(X8, X9, X10, X11, SI, 10, 8, 7, 1, 2, 4, 6, 5, 15, 9, 3, 13, 11, 14, 12, 0); \
ROUND_SSSE3(X4, X5, X6, X7, X8, X9, X10, X11, X8, X13, X14)
#define HASH_BLOCKS(h, c, flag, blocks_base, blocks_len, BLAKE2s_FUNC) \
MOVQ h, AX; \
MOVQ c, BX; \
MOVL flag, CX; \
MOVQ blocks_base, SI; \
MOVQ blocks_len, DX; \
\
MOVQ SP, BP; \
MOVQ SP, R9; \
ADDQ $15, R9; \
ANDQ $~15, R9; \
MOVQ R9, SP; \
\
MOVQ 0(BX), R9; \
MOVQ R9, 0(SP); \
XORQ R9, R9; \
MOVQ R9, 8(SP); \
MOVL CX, 8(SP); \
\
MOVOU 0(AX), X0; \
MOVOU 16(AX), X1; \
MOVOU iv0<>(SB), X2; \
MOVOU iv1<>(SB), X3 \
\
MOVOU counter<>(SB), X12; \
MOVOU rol16<>(SB), X13; \
MOVOU rol8<>(SB), X14; \
MOVO 0(SP), X15; \
\
loop: \
MOVO X0, X4; \
MOVO X1, X5; \
MOVO X2, X6; \
MOVO X3, X7; \
\
PADDQ X12, X15; \
PXOR X15, X7; \
\
BLAKE2s_FUNC(); \
\
PXOR X4, X0; \
PXOR X5, X1; \
PXOR X6, X0; \
PXOR X7, X1; \
\
LEAQ 64(SI), SI; \
SUBQ $64, DX; \
JNE loop; \
\
MOVO X15, 0(SP); \
MOVQ 0(SP), R9; \
MOVQ R9, 0(BX); \
\
MOVOU X0, 0(AX); \
MOVOU X1, 16(AX); \
\
MOVQ BP, SP
// func hashBlocksSSE2(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte)
TEXT ·hashBlocksSSE2(SB), 0, $672-48 // frame = 656 + 16 byte alignment
HASH_BLOCKS(h+0(FP), c+8(FP), flag+16(FP), blocks_base+24(FP), blocks_len+32(FP), BLAKE2s_SSE2)
RET
// func hashBlocksSSSE3(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte)
TEXT ·hashBlocksSSSE3(SB), 0, $672-48 // frame = 656 + 16 byte alignment
HASH_BLOCKS(h+0(FP), c+8(FP), flag+16(FP), blocks_base+24(FP), blocks_len+32(FP), BLAKE2s_SSSE3)
RET
// func hashBlocksSSE4(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte)
TEXT ·hashBlocksSSE4(SB), 0, $32-48 // frame = 16 + 16 byte alignment
HASH_BLOCKS(h+0(FP), c+8(FP), flag+16(FP), blocks_base+24(FP), blocks_len+32(FP), BLAKE2s_SSE4)
RET

174
vendor/golang.org/x/crypto/blake2s/blake2s_generic.go generated vendored Normal file
View file

@ -0,0 +1,174 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package blake2s
// the precomputed values for BLAKE2s
// there are 10 16-byte arrays - one for each round
// the entries are calculated from the sigma constants.
var precomputed = [10][16]byte{
{0, 2, 4, 6, 1, 3, 5, 7, 8, 10, 12, 14, 9, 11, 13, 15},
{14, 4, 9, 13, 10, 8, 15, 6, 1, 0, 11, 5, 12, 2, 7, 3},
{11, 12, 5, 15, 8, 0, 2, 13, 10, 3, 7, 9, 14, 6, 1, 4},
{7, 3, 13, 11, 9, 1, 12, 14, 2, 5, 4, 15, 6, 10, 0, 8},
{9, 5, 2, 10, 0, 7, 4, 15, 14, 11, 6, 3, 1, 12, 8, 13},
{2, 6, 0, 8, 12, 10, 11, 3, 4, 7, 15, 1, 13, 5, 14, 9},
{12, 1, 14, 4, 5, 15, 13, 10, 0, 6, 9, 8, 7, 3, 2, 11},
{13, 7, 12, 3, 11, 14, 1, 9, 5, 15, 8, 2, 0, 4, 6, 10},
{6, 14, 11, 0, 15, 9, 3, 8, 12, 13, 1, 10, 2, 7, 4, 5},
{10, 8, 7, 1, 2, 4, 6, 5, 15, 9, 3, 13, 11, 14, 12, 0},
}
func hashBlocksGeneric(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte) {
var m [16]uint32
c0, c1 := c[0], c[1]
for i := 0; i < len(blocks); {
c0 += BlockSize
if c0 < BlockSize {
c1++
}
v0, v1, v2, v3, v4, v5, v6, v7 := h[0], h[1], h[2], h[3], h[4], h[5], h[6], h[7]
v8, v9, v10, v11, v12, v13, v14, v15 := iv[0], iv[1], iv[2], iv[3], iv[4], iv[5], iv[6], iv[7]
v12 ^= c0
v13 ^= c1
v14 ^= flag
for j := range m {
m[j] = uint32(blocks[i]) | uint32(blocks[i+1])<<8 | uint32(blocks[i+2])<<16 | uint32(blocks[i+3])<<24
i += 4
}
for k := range precomputed {
s := &(precomputed[k])
v0 += m[s[0]]
v0 += v4
v12 ^= v0
v12 = v12<<(32-16) | v12>>16
v8 += v12
v4 ^= v8
v4 = v4<<(32-12) | v4>>12
v1 += m[s[1]]
v1 += v5
v13 ^= v1
v13 = v13<<(32-16) | v13>>16
v9 += v13
v5 ^= v9
v5 = v5<<(32-12) | v5>>12
v2 += m[s[2]]
v2 += v6
v14 ^= v2
v14 = v14<<(32-16) | v14>>16
v10 += v14
v6 ^= v10
v6 = v6<<(32-12) | v6>>12
v3 += m[s[3]]
v3 += v7
v15 ^= v3
v15 = v15<<(32-16) | v15>>16
v11 += v15
v7 ^= v11
v7 = v7<<(32-12) | v7>>12
v0 += m[s[4]]
v0 += v4
v12 ^= v0
v12 = v12<<(32-8) | v12>>8
v8 += v12
v4 ^= v8
v4 = v4<<(32-7) | v4>>7
v1 += m[s[5]]
v1 += v5
v13 ^= v1
v13 = v13<<(32-8) | v13>>8
v9 += v13
v5 ^= v9
v5 = v5<<(32-7) | v5>>7
v2 += m[s[6]]
v2 += v6
v14 ^= v2
v14 = v14<<(32-8) | v14>>8
v10 += v14
v6 ^= v10
v6 = v6<<(32-7) | v6>>7
v3 += m[s[7]]
v3 += v7
v15 ^= v3
v15 = v15<<(32-8) | v15>>8
v11 += v15
v7 ^= v11
v7 = v7<<(32-7) | v7>>7
v0 += m[s[8]]
v0 += v5
v15 ^= v0
v15 = v15<<(32-16) | v15>>16
v10 += v15
v5 ^= v10
v5 = v5<<(32-12) | v5>>12
v1 += m[s[9]]
v1 += v6
v12 ^= v1
v12 = v12<<(32-16) | v12>>16
v11 += v12
v6 ^= v11
v6 = v6<<(32-12) | v6>>12
v2 += m[s[10]]
v2 += v7
v13 ^= v2
v13 = v13<<(32-16) | v13>>16
v8 += v13
v7 ^= v8
v7 = v7<<(32-12) | v7>>12
v3 += m[s[11]]
v3 += v4
v14 ^= v3
v14 = v14<<(32-16) | v14>>16
v9 += v14
v4 ^= v9
v4 = v4<<(32-12) | v4>>12
v0 += m[s[12]]
v0 += v5
v15 ^= v0
v15 = v15<<(32-8) | v15>>8
v10 += v15
v5 ^= v10
v5 = v5<<(32-7) | v5>>7
v1 += m[s[13]]
v1 += v6
v12 ^= v1
v12 = v12<<(32-8) | v12>>8
v11 += v12
v6 ^= v11
v6 = v6<<(32-7) | v6>>7
v2 += m[s[14]]
v2 += v7
v13 ^= v2
v13 = v13<<(32-8) | v13>>8
v8 += v13
v7 ^= v8
v7 = v7<<(32-7) | v7>>7
v3 += m[s[15]]
v3 += v4
v14 ^= v3
v14 = v14<<(32-8) | v14>>8
v9 += v14
v4 ^= v9
v4 = v4<<(32-7) | v4>>7
}
h[0] ^= v0 ^ v8
h[1] ^= v1 ^ v9
h[2] ^= v2 ^ v10
h[3] ^= v3 ^ v11
h[4] ^= v4 ^ v12
h[5] ^= v5 ^ v13
h[6] ^= v6 ^ v14
h[7] ^= v7 ^ v15
}
c[0], c[1] = c0, c1
}

17
vendor/golang.org/x/crypto/blake2s/blake2s_ref.go generated vendored Normal file
View file

@ -0,0 +1,17 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build !amd64,!386 gccgo appengine
package blake2s
var (
useSSE4 = false
useSSSE3 = false
useSSE2 = false
)
func hashBlocks(h *[8]uint32, c *[2]uint32, flag uint32, blocks []byte) {
hashBlocksGeneric(h, c, flag, blocks)
}

178
vendor/golang.org/x/crypto/blake2s/blake2x.go generated vendored Normal file
View file

@ -0,0 +1,178 @@
// Copyright 2017 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package blake2s
import (
"encoding/binary"
"errors"
"io"
)
// XOF defines the interface to hash functions that
// support arbitrary-length output.
type XOF interface {
// Write absorbs more data into the hash's state. It panics if called
// after Read.
io.Writer
// Read reads more output from the hash. It returns io.EOF if the limit
// has been reached.
io.Reader
// Clone returns a copy of the XOF in its current state.
Clone() XOF
// Reset resets the XOF to its initial state.
Reset()
}
// OutputLengthUnknown can be used as the size argument to NewXOF to indicate
// the the length of the output is not known in advance.
const OutputLengthUnknown = 0
// magicUnknownOutputLength is a magic value for the output size that indicates
// an unknown number of output bytes.
const magicUnknownOutputLength = 65535
// maxOutputLength is the absolute maximum number of bytes to produce when the
// number of output bytes is unknown.
const maxOutputLength = (1 << 32) * 32
// NewXOF creates a new variable-output-length hash. The hash either produce a
// known number of bytes (1 <= size < 65535), or an unknown number of bytes
// (size == OutputLengthUnknown). In the latter case, an absolute limit of
// 128GiB applies.
//
// A non-nil key turns the hash into a MAC. The key must between
// zero and 32 bytes long.
func NewXOF(size uint16, key []byte) (XOF, error) {
if len(key) > Size {
return nil, errKeySize
}
if size == magicUnknownOutputLength {
// 2^16-1 indicates an unknown number of bytes and thus isn't a
// valid length.
return nil, errors.New("blake2s: XOF length too large")
}
if size == OutputLengthUnknown {
size = magicUnknownOutputLength
}
x := &xof{
d: digest{
size: Size,
keyLen: len(key),
},
length: size,
}
copy(x.d.key[:], key)
x.Reset()
return x, nil
}
type xof struct {
d digest
length uint16
remaining uint64
cfg, root, block [Size]byte
offset int
nodeOffset uint32
readMode bool
}
func (x *xof) Write(p []byte) (n int, err error) {
if x.readMode {
panic("blake2s: write to XOF after read")
}
return x.d.Write(p)
}
func (x *xof) Clone() XOF {
clone := *x
return &clone
}
func (x *xof) Reset() {
x.cfg[0] = byte(Size)
binary.LittleEndian.PutUint32(x.cfg[4:], uint32(Size)) // leaf length
binary.LittleEndian.PutUint16(x.cfg[12:], x.length) // XOF length
x.cfg[15] = byte(Size) // inner hash size
x.d.Reset()
x.d.h[3] ^= uint32(x.length)
x.remaining = uint64(x.length)
if x.remaining == magicUnknownOutputLength {
x.remaining = maxOutputLength
}
x.offset, x.nodeOffset = 0, 0
x.readMode = false
}
func (x *xof) Read(p []byte) (n int, err error) {
if !x.readMode {
x.d.finalize(&x.root)
x.readMode = true
}
if x.remaining == 0 {
return 0, io.EOF
}
n = len(p)
if uint64(n) > x.remaining {
n = int(x.remaining)
p = p[:n]
}
if x.offset > 0 {
blockRemaining := Size - x.offset
if n < blockRemaining {
x.offset += copy(p, x.block[x.offset:])
x.remaining -= uint64(n)
return
}
copy(p, x.block[x.offset:])
p = p[blockRemaining:]
x.offset = 0
x.remaining -= uint64(blockRemaining)
}
for len(p) >= Size {
binary.LittleEndian.PutUint32(x.cfg[8:], x.nodeOffset)
x.nodeOffset++
x.d.initConfig(&x.cfg)
x.d.Write(x.root[:])
x.d.finalize(&x.block)
copy(p, x.block[:])
p = p[Size:]
x.remaining -= uint64(Size)
}
if todo := len(p); todo > 0 {
if x.remaining < uint64(Size) {
x.cfg[0] = byte(x.remaining)
}
binary.LittleEndian.PutUint32(x.cfg[8:], x.nodeOffset)
x.nodeOffset++
x.d.initConfig(&x.cfg)
x.d.Write(x.root[:])
x.d.finalize(&x.block)
x.offset = copy(p, x.block[:todo])
x.remaining -= uint64(todo)
}
return
}
func (d *digest) initConfig(cfg *[Size]byte) {
d.offset, d.c[0], d.c[1] = 0, 0, 0
for i := range d.h {
d.h[i] = iv[i] ^ binary.LittleEndian.Uint32(cfg[i*4:])
}
}

21
vendor/golang.org/x/crypto/blake2s/register.go generated vendored Normal file
View file

@ -0,0 +1,21 @@
// Copyright 2017 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build go1.9
package blake2s
import (
"crypto"
"hash"
)
func init() {
newHash256 := func() hash.Hash {
h, _ := New256(nil)
return h
}
crypto.RegisterHash(crypto.BLAKE2s_256, newHash256)
}

38
vendor/golang.org/x/sys/cpu/cpu.go generated vendored Normal file
View file

@ -0,0 +1,38 @@
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package cpu implements processor feature detection for
// various CPU architectures.
package cpu
// CacheLinePad is used to pad structs to avoid false sharing.
type CacheLinePad struct{ _ [cacheLineSize]byte }
// X86 contains the supported CPU features of the
// current X86/AMD64 platform. If the current platform
// is not X86/AMD64 then all feature flags are false.
//
// X86 is padded to avoid false sharing. Further the HasAVX
// and HasAVX2 are only set if the OS supports XMM and YMM
// registers in addition to the CPUID feature bit being set.
var X86 struct {
_ CacheLinePad
HasAES bool // AES hardware implementation (AES NI)
HasADX bool // Multi-precision add-carry instruction extensions
HasAVX bool // Advanced vector extension
HasAVX2 bool // Advanced vector extension 2
HasBMI1 bool // Bit manipulation instruction set 1
HasBMI2 bool // Bit manipulation instruction set 2
HasERMS bool // Enhanced REP for MOVSB and STOSB
HasFMA bool // Fused-multiply-add instructions
HasOSXSAVE bool // OS supports XSAVE/XRESTOR for saving/restoring XMM registers.
HasPCLMULQDQ bool // PCLMULQDQ instruction - most often used for AES-GCM
HasPOPCNT bool // Hamming weight instruction POPCNT.
HasSSE2 bool // Streaming SIMD extension 2 (always available on amd64)
HasSSE3 bool // Streaming SIMD extension 3
HasSSSE3 bool // Supplemental streaming SIMD extension 3
HasSSE41 bool // Streaming SIMD extension 4 and 4.1
HasSSE42 bool // Streaming SIMD extension 4 and 4.2
_ CacheLinePad
}

7
vendor/golang.org/x/sys/cpu/cpu_arm.go generated vendored Normal file
View file

@ -0,0 +1,7 @@
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package cpu
const cacheLineSize = 32

7
vendor/golang.org/x/sys/cpu/cpu_arm64.go generated vendored Normal file
View file

@ -0,0 +1,7 @@
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package cpu
const cacheLineSize = 64

16
vendor/golang.org/x/sys/cpu/cpu_gc_x86.go generated vendored Normal file
View file

@ -0,0 +1,16 @@
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build 386 amd64 amd64p32
// +build !gccgo
package cpu
// cpuid is implemented in cpu_x86.s for gc compiler
// and in cpu_gccgo.c for gccgo.
func cpuid(eaxArg, ecxArg uint32) (eax, ebx, ecx, edx uint32)
// xgetbv with ecx = 0 is implemented in cpu_x86.s for gc compiler
// and in cpu_gccgo.c for gccgo.
func xgetbv() (eax, edx uint32)

43
vendor/golang.org/x/sys/cpu/cpu_gccgo.c generated vendored Normal file
View file

@ -0,0 +1,43 @@
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build 386 amd64 amd64p32
// +build gccgo
#include <cpuid.h>
#include <stdint.h>
// Need to wrap __get_cpuid_count because it's declared as static.
int
gccgoGetCpuidCount(uint32_t leaf, uint32_t subleaf,
uint32_t *eax, uint32_t *ebx,
uint32_t *ecx, uint32_t *edx)
{
return __get_cpuid_count(leaf, subleaf, eax, ebx, ecx, edx);
}
// xgetbv reads the contents of an XCR (Extended Control Register)
// specified in the ECX register into registers EDX:EAX.
// Currently, the only supported value for XCR is 0.
//
// TODO: Replace with a better alternative:
//
// #include <xsaveintrin.h>
//
// #pragma GCC target("xsave")
//
// void gccgoXgetbv(uint32_t *eax, uint32_t *edx) {
// unsigned long long x = _xgetbv(0);
// *eax = x & 0xffffffff;
// *edx = (x >> 32) & 0xffffffff;
// }
//
// Note that _xgetbv is defined starting with GCC 8.
void
gccgoXgetbv(uint32_t *eax, uint32_t *edx)
{
__asm(" xorl %%ecx, %%ecx\n"
" xgetbv"
: "=a"(*eax), "=d"(*edx));
}

26
vendor/golang.org/x/sys/cpu/cpu_gccgo.go generated vendored Normal file
View file

@ -0,0 +1,26 @@
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build 386 amd64 amd64p32
// +build gccgo
package cpu
//extern gccgoGetCpuidCount
func gccgoGetCpuidCount(eaxArg, ecxArg uint32, eax, ebx, ecx, edx *uint32)
func cpuid(eaxArg, ecxArg uint32) (eax, ebx, ecx, edx uint32) {
var a, b, c, d uint32
gccgoGetCpuidCount(eaxArg, ecxArg, &a, &b, &c, &d)
return a, b, c, d
}
//extern gccgoXgetbv
func gccgoXgetbv(eax, edx *uint32)
func xgetbv() (eax, edx uint32) {
var a, d uint32
gccgoXgetbv(&a, &d)
return a, d
}

9
vendor/golang.org/x/sys/cpu/cpu_mips64x.go generated vendored Normal file
View file

@ -0,0 +1,9 @@
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build mips64 mips64le
package cpu
const cacheLineSize = 32

9
vendor/golang.org/x/sys/cpu/cpu_mipsx.go generated vendored Normal file
View file

@ -0,0 +1,9 @@
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build mips mipsle
package cpu
const cacheLineSize = 32

9
vendor/golang.org/x/sys/cpu/cpu_ppc64x.go generated vendored Normal file
View file

@ -0,0 +1,9 @@
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build ppc64 ppc64le
package cpu
const cacheLineSize = 128

7
vendor/golang.org/x/sys/cpu/cpu_s390x.go generated vendored Normal file
View file

@ -0,0 +1,7 @@
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package cpu
const cacheLineSize = 256

55
vendor/golang.org/x/sys/cpu/cpu_x86.go generated vendored Normal file
View file

@ -0,0 +1,55 @@
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build 386 amd64 amd64p32
package cpu
const cacheLineSize = 64
func init() {
maxID, _, _, _ := cpuid(0, 0)
if maxID < 1 {
return
}
_, _, ecx1, edx1 := cpuid(1, 0)
X86.HasSSE2 = isSet(26, edx1)
X86.HasSSE3 = isSet(0, ecx1)
X86.HasPCLMULQDQ = isSet(1, ecx1)
X86.HasSSSE3 = isSet(9, ecx1)
X86.HasFMA = isSet(12, ecx1)
X86.HasSSE41 = isSet(19, ecx1)
X86.HasSSE42 = isSet(20, ecx1)
X86.HasPOPCNT = isSet(23, ecx1)
X86.HasAES = isSet(25, ecx1)
X86.HasOSXSAVE = isSet(27, ecx1)
osSupportsAVX := false
// For XGETBV, OSXSAVE bit is required and sufficient.
if X86.HasOSXSAVE {
eax, _ := xgetbv()
// Check if XMM and YMM registers have OS support.
osSupportsAVX = isSet(1, eax) && isSet(2, eax)
}
X86.HasAVX = isSet(28, ecx1) && osSupportsAVX
if maxID < 7 {
return
}
_, ebx7, _, _ := cpuid(7, 0)
X86.HasBMI1 = isSet(3, ebx7)
X86.HasAVX2 = isSet(5, ebx7) && osSupportsAVX
X86.HasBMI2 = isSet(8, ebx7)
X86.HasERMS = isSet(9, ebx7)
X86.HasADX = isSet(19, ebx7)
}
func isSet(bitpos uint, value uint32) bool {
return value&(1<<bitpos) != 0
}

27
vendor/golang.org/x/sys/cpu/cpu_x86.s generated vendored Normal file
View file

@ -0,0 +1,27 @@
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build 386 amd64 amd64p32
// +build !gccgo
#include "textflag.h"
// func cpuid(eaxArg, ecxArg uint32) (eax, ebx, ecx, edx uint32)
TEXT ·cpuid(SB), NOSPLIT, $0-24
MOVL eaxArg+0(FP), AX
MOVL ecxArg+4(FP), CX
CPUID
MOVL AX, eax+8(FP)
MOVL BX, ebx+12(FP)
MOVL CX, ecx+16(FP)
MOVL DX, edx+20(FP)
RET
// func xgetbv() (eax, edx uint32)
TEXT ·xgetbv(SB),NOSPLIT,$0-8
MOVL $0, CX
XGETBV
MOVL AX, eax+0(FP)
MOVL DX, edx+4(FP)
RET