cryptonight hash functions in go assembler
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Loki Verloren 45bdbf8b24
Merge remote-tracking branch 'origin/master'
3 months ago
.circleci retargeted 3 months ago
cmd/cnhash retargeted 3 months ago
groestl retargeted 3 months ago
internal retargeted 3 months ago
jh retargeted 3 months ago
.gitattributes split assembly files 1 year ago
.gitignore clean files, add README 1 year ago
LICENSE clean files, add README 1 year ago
README.adoc retargeted 3 months ago
arith_amd64.go split v2Sqrt and tests 1 year ago
arith_amd64.s rename some variables 1 year ago
arith_ref.go fix ref function signature 1 year ago
arith_test.go split v2Sqrt and tests 1 year ago
cryptonight.go retargeted 3 months ago
cryptonight_test.go retargeted 3 months ago
difficulty.go diff: fix algorithm 1 year ago
difficulty_test.go diff: fix algorithm 1 year ago
example_test.go update to the latest v2 tweak 1 year ago
final_hash.go retargeted 3 months ago
go.mod updating mod 3 months ago
go.sum updating mod 3 months ago
sum_amd64.go retargeted 3 months ago
sum_amd64_test.go test: early return 1 year ago
sum_defs_amd64.h rename some variables 1 year ago
sum_generic.go assembly implementation of memhard for amd64 1 year ago
sum_ref.go retargeted 3 months ago
sum_ref_test.go split v2Sqrt and tests 1 year ago
sum_v0_amd64.s asm: lint 1 year ago
sum_v1_amd64.s asm: lint 1 year ago
sum_v2_amd64.s v2: asm: reduce move from xmm 1 year ago

README.adoc

lang="en">

GoDoc tag CircleCI Codecov Go Report Card License

Pure Go/ASM implementation of CryptoNight hash function and some of its variant, without any CGO binding.

Features

  • Support Monero v7 variant, and also the upcoming variant 2!

  • No CGO hell, making builds easier and faster.

  • Hardware acceleration available for amd64 architecture.

  • Use of an internal sync.Pool to manage caches, since it is memory hard.

Install

$ go get -u git.parallelcoin.io/dev/cryptonight

A simple CLI utility is also available with go get -u git.parallelcoin.io/dev/cryptonight/cmd/cnhash.

Usage of cnhash:
  -bench
        Benchmark mode, don't do anything else.
  -in-file string
        Read input from file instead of stdin.
  -in-hex
        Read input in hex instead of binary.
  -include-diff
        Append the difficulty of the result hash to the output. If -out-binary is not given,
the difficulty will be appeneded to the output in decimal with comma separated (CSV friendly)
, otherwise it will be appeneded to the hash binary (which is 32 bytes long) directly, in 8
bytes little endian.
  -out-binary
        Produce output in binary (little endian) instead of hex.
  -out-file string
        Produce output to file instead of stdout.
  -variant int
        Set CryptoNight variant, default 0. This applies to benchmark mode as well.

Example

package main

import (
    "fmt"

    "git.parallelcoin.io/dev/cryptonight"
)

func main() {
    blob := []byte("Hello, 世界")
    fmt.Printf("%x\n", cryptonight.Sum(blob, 0)) // original
    // Output: 0999794e4e20d86e6a81b54495aeb370b6a9ae795fb5af4f778afaf07c0b2e0e

    blob = []byte("variant 1 requires at least 43 bytes of input.")
    fmt.Printf("%x\n", cryptonight.Sum(blob, 1)) // variant 1
    // Output: 261124c5a6dca5d4aa3667d328a94ead9a819ae714e1f1dc113ceeb14f1ecf99

    blob = []byte("Monero is cash for a connected world. It’s fast, private, and secure.")
    fmt.Printf("%x\n", cryptonight.Sum(blob, 2)) // variant 2
    // Output: abb61f40468c70234051e4bb5e8b670812473b2a71e02c9633ef94996a621b96
}

Tested architectures

  • amd64 (w/ AVX, SSE, AES)

  • amd64 (w/o AVX, SSE, AES)

  • 386

  • arm64

Benchmarks

CPU: 4 x Intel® Xeon® CPU E3-1270 v3 @ 3.50GHz

goos: linux
goarch: amd64
pkg: git.parallelcoin.io/dev/cryptonight
BenchmarkSum/v0-4            100   20208070 ns/op   21584 B/op   2 allocs/op
BenchmarkSum/v1-4            100   20535318 ns/op   21584 B/op   2 allocs/op
BenchmarkSum/v2-4            100   22328893 ns/op   21584 B/op   2 allocs/op
BenchmarkSum/v0-parallel-4   100   10798945 ns/op   42664 B/op   2 allocs/op
BenchmarkSum/v1-parallel-4   100   10316040 ns/op   42655 B/op   2 allocs/op
BenchmarkSum/v2-parallel-4   100   11740615 ns/op   42661 B/op   2 allocs/op
PASS

Development

While this repository is already out-of-box, which means what you need to do to use it in your code is just a go get (or dep ensure -add whatsoever), in case you want to hack on this library, some additional steps are required since it uses code generation.

Preprocess

If you modified a source file in this library that uses C-kind macros (the comments tells), in order to expand them and generate the final code, cpp(1) is needed, which a part of GCC toolchain and should be already available if you have installed gcc (or MinGW for Windows) in your machine.

Once some modification is made in a file that used macro, simply use go generate git.parallelcoin.io/dev/cryptonight/... to run the gcc preprocessor on them.

Packages information

git.parallelcoin.io/dev/cryptonight/internal/aes

From Go’s crypto/aes. Since CryptoNight’s use of AES is quite non-standard and not intended for encryption, you must use this package this package with care for project that’s not CryptoNight associated.

git.parallelcoin.io/dev/cryptonight/internal/sha3

From Go’s golang.org/x/crypto/sha3. All CryptoNight specific additional works are made in cn.go only; other files are untouched at all.

git.parallelcoin.io/dev/cryptonight/groestl

Grøstl-256 implementation. It is directly ported from C and not quite optimized.

git.parallelcoin.io/dev/cryptonight/jh

JH-256 implementation. It is directly ported from C and not quite optimized.

Tests, coverage and benchmarks

$ go test -v -race -coverprofile=coverage.txt -covermode=atomic
$ go tool cover -html=coverage.txt
$ go test -v -run=^$ -bench=. -benchmem

TODO

  • ❏ ARM64-specific optimization

  • ✓ Tests on other architectures

  • ✓ Improve performance for variant 2

  • ❏ Improve performance for groestl and jh

  • ✓ Try a nearly full assembly implementation (except for the final hash) for amd64

Donation

If you find this lib helpful, maybe consider buying me a cup of coffee at

XMR

4777777jHFbZB4gyqrB1JHDtrGFusyj4b3M2nScYDPKEM133ng2QDrK9ycqizXS2XofADw5do5rU19LQmpTGCfeQTerm1Ti

BTC

1Eqqqq9xR78wJyRXXgvR73HEfKdEwq68BT

Much thanks.

License

MIT