Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: xelpool/xelishash
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v1.6.0
Choose a base ref
...
head repository: xelpool/xelishash
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: master
Choose a head ref
  • 3 commits
  • 5 files changed
  • 1 contributor

Commits on Jul 7, 2024

  1. fix xelis hash v2

    duggavo committed Jul 7, 2024
    Copy the full SHA
    75a0d96 View commit details

Commits on Jan 7, 2025

  1. Copy the full SHA
    64ae0ab View commit details
  2. Copy the full SHA
    5b9292f View commit details
Showing with 92 additions and 44 deletions.
  1. +3 −3 go.mod
  2. +19 −4 go.sum
  3. +41 −13 threadpool_test.go
  4. +13 −16 xelishashv2.go
  5. +16 −8 xelishashv2_test.go
6 changes: 3 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
@@ -3,12 +3,12 @@ module github.com/xelpool/xelishash
go 1.20.0

require (
github.com/chocolatkey/chacha8 v0.0.0-20200308092524-06a0ce7f6716
github.com/zeebo/blake3 v0.2.3
golang.org/x/crypto v0.24.0
lukechampine.com/uint128 v1.3.0
)

require (
github.com/klauspost/cpuid/v2 v2.0.12 // indirect
golang.org/x/sys v0.21.0 // indirect
github.com/klauspost/cpuid/v2 v2.2.8 // indirect
golang.org/x/sys v0.22.0 // indirect
)
23 changes: 19 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,14 +1,29 @@
github.com/chocolatkey/chacha8 v0.0.0-20200308092524-06a0ce7f6716 h1:NSjnwJb5rlX8weAJPotMIFtWSFt4Tjtkjt7nTBil1dA=
github.com/chocolatkey/chacha8 v0.0.0-20200308092524-06a0ce7f6716/go.mod h1:NvCEVATmyDtfApL4hee9mqF2c7+AFTpltRm62q68ppU=
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/klauspost/cpuid/v2 v2.0.12 h1:p9dKCg8i4gmOxtv35DvrYoWqYzQrvEVdjQ762Y0OqZE=
github.com/klauspost/cpuid/v2 v2.0.12/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c=
github.com/klauspost/cpuid/v2 v2.2.8 h1:+StwCXwm9PdpiEkPyzBXIy+M9KUb4ODm0Zarf1kS5BM=
github.com/klauspost/cpuid/v2 v2.2.8/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/zeebo/assert v1.1.0 h1:hU1L1vLTHsnO8x8c9KAR5GmM5QscxHg5RNU5z5qbUWY=
github.com/zeebo/assert v1.1.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0=
github.com/zeebo/blake3 v0.2.3 h1:TFoLXsjeXqRNFxSbk35Dk4YtszE/MQQGK10BH4ptoTg=
github.com/zeebo/blake3 v0.2.3/go.mod h1:mjJjZpnsyIVtVgTOSpJ9vmRE4wgDeyt2HU3qXvvKCaQ=
github.com/zeebo/pcg v1.0.1 h1:lyqfGeWiv4ahac6ttHs+I5hwtH/+1mrhlCtVNQM2kHo=
github.com/zeebo/pcg v1.0.1/go.mod h1:09F0S9iiKrwn9rlI5yjLkmrug154/YRW6KnnXVDM/l4=
golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI=
golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM=
golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.0.0-20190902133755-9109b7679e13 h1:tdsQdquKbTNMsSZLqnLELJGzCANp9oXhu6zFBW6ODx4=
golang.org/x/sys v0.0.0-20190902133755-9109b7679e13/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
lukechampine.com/uint128 v1.3.0 h1:cDdUVfRwDUDovz610ABgFD17nXD4/uDgVHl2sC3+sbo=
lukechampine.com/uint128 v1.3.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk=
54 changes: 41 additions & 13 deletions threadpool_test.go
Original file line number Diff line number Diff line change
@@ -24,22 +24,50 @@ func TestThreadPool(t *testing.T) {
inputV2 := input[:112]

expectedHashV2 := [32]byte{
203, 44, 144, 190, 181, 16, 222, 35, 137, 147,
96, 136, 37, 100, 199, 84, 29, 116, 0, 38, 178,
224, 189, 9, 224, 32, 45, 235, 130, 177, 255, 40,
126, 219, 112, 240, 116, 133, 115, 144, 39, 40, 164,
105, 30, 158, 45, 126, 64, 67, 238, 52, 200, 35,
161, 19, 144, 211, 214, 225, 95, 190, 146, 27,
}

for i2 := 0; i2 < 8; i2++ {
go func() {
result := tp.XelisHashV2(inputV2)
t.Logf("xelishash v2 result: %x", result)
if result != expectedHashV2 {
panic(fmt.Errorf("invalid result %x, expected %x", result, expectedHashV2))
}
endchan <- true
}()
inputV2_2 := []byte{
172, 236, 108, 212, 181, 31, 109, 45, 44, 242, 54, 225, 143, 133,
89, 44, 179, 108, 39, 191, 32, 116, 229, 33, 63, 130, 33, 120, 185, 89,
146, 141, 10, 79, 183, 107, 238, 122, 92, 222, 25, 134, 90, 107, 116,
110, 236, 53, 255, 5, 214, 126, 24, 216, 97, 199, 148, 239, 253, 102,
199, 184, 232, 253, 158, 145, 86, 187, 112, 81, 78, 70, 80, 110, 33,
37, 159, 233, 198, 1, 178, 108, 210, 100, 109, 155, 106, 124, 124, 83,
89, 50, 197, 115, 231, 32, 74, 2, 92, 47, 25, 220, 135, 249, 122,
172, 220, 137, 143, 234, 68, 188,
}

expectedHashV2_2 := [32]byte{
199, 114, 154, 28, 4, 164, 196, 178, 117, 17, 148,
203, 125, 228, 51, 145, 162, 222, 106, 202, 205,
55, 244, 178, 94, 29, 248, 242, 98, 221, 158, 179,
}

for i2 := 0; i2 < 50; i2++ {
if i2%2 == 0 {
go func() {
result := tp.XelisHashV2(inputV2)
t.Logf("xelishash v2 result 1: %x", result)
if result != expectedHashV2 {
panic(fmt.Errorf("invalid result %x, expected %x", result, expectedHashV2))
}
endchan <- true
}()
} else {
go func() {
result := tp.XelisHashV2(inputV2_2)
t.Logf("xelishash v2 result 2: %x", result)
if result != expectedHashV2_2 {
panic(fmt.Errorf("invalid result %x, expected %x", result, expectedHashV2))
}
endchan <- true
}()
}
}
for i := 0; i < 8; i++ {
for i := 0; i < 50; i++ {
<-endchan
}
}
29 changes: 13 additions & 16 deletions xelishashv2.go
Original file line number Diff line number Diff line change
@@ -5,8 +5,8 @@ import (
"math/bits"
"unsafe"

"github.com/chocolatkey/chacha8"
"github.com/zeebo/blake3"
"golang.org/x/crypto/chacha20"
"lukechampine.com/uint128"
)

@@ -36,7 +36,7 @@ type ScratchPadV2 [MEMORY_SIZE_V2]uint64

// Stage 1 of the hashing algorithm
// This stage is responsible for generating the scratch pad
// The scratch pad is generated using Chacha20 with a custom nonce
// The scratch pad is generated using Chacha8 with a custom nonce
// that is updated after each iteration
func stage_1_v2(input []byte, scratch_pad *[MEMORY_SIZE_V2 * 8]byte) {
output_offset := 0
@@ -49,16 +49,17 @@ func stage_1_v2(input []byte, scratch_pad *[MEMORY_SIZE_V2 * 8]byte) {
num_chunks := (len(input) + CHUNK_SIZE_V2 - 1) / CHUNK_SIZE_V2

for chunk_index := 0; chunk_index < num_chunks; chunk_index++ {
// Pad the chunk to 32 bytes if it is shorter
chunk := input[chunk_index*CHUNK_SIZE_V2:]
if len(chunk) > CHUNK_SIZE_V2 {
chunk = chunk[:CHUNK_SIZE_V2]
}

key := [CHUNK_SIZE_V2]byte{}
copy(key[:CHUNK_SIZE_V2], chunk)
// Concatenate the input hash with the chunk
tmp := [HASH_SIZE * 2]byte{}
copy(tmp[0:HASH_SIZE], input_hash[:])
copy(tmp[HASH_SIZE:], chunk)

// Hash it to not trust the input
input_hash = blake3.Sum256(tmp[:])

cipher, err := chacha20.NewUnauthenticatedCipher(key[:], nonce[:])
cipher, err := chacha8.New(input_hash[:], nonce[:])
if err != nil {
panic(err)
}
@@ -72,14 +73,10 @@ func stage_1_v2(input []byte, scratch_pad *[MEMORY_SIZE_V2 * 8]byte) {
current_output_size = chunk_output_size
}

temp_output := make([]byte, current_output_size)

// Apply the keystream to the output
cipher.XORKeyStream(temp_output, temp_output)

// Copy the output to the scratch pad
offset := chunk_index * current_output_size
copy(scratch_pad[offset:offset+current_output_size], temp_output)
part := scratch_pad[offset : offset+current_output_size]
cipher.KeyStream(part)

output_offset += current_output_size

@@ -90,7 +87,7 @@ func stage_1_v2(input []byte, scratch_pad *[MEMORY_SIZE_V2 * 8]byte) {
}

// Copy the new nonce
copy(nonce[:], temp_output[nonce_start:])
copy(nonce[:], part[nonce_start:])
}
}

24 changes: 16 additions & 8 deletions xelishashv2_test.go
Original file line number Diff line number Diff line change
@@ -26,9 +26,9 @@ func TestZeroHash(t *testing.T) {

hash := XelisHashV2(input, &scratchpad)
expectedHash := [32]byte{
203, 44, 144, 190, 181, 16, 222, 35, 137, 147,
96, 136, 37, 100, 199, 84, 29, 116, 0, 38, 178,
224, 189, 9, 224, 32, 45, 235, 130, 177, 255, 40,
126, 219, 112, 240, 116, 133, 115, 144, 39, 40, 164,
105, 30, 158, 45, 126, 64, 67, 238, 52, 200, 35,
161, 19, 144, 211, 214, 225, 95, 190, 146, 27,
}

if hash != expectedHash {
@@ -47,20 +47,28 @@ func TestVerifyOutput(t *testing.T) {
89, 50, 197, 115, 231, 32, 74, 2, 92, 47, 25, 220, 135, 249, 122,
172, 220, 137, 143, 234, 68, 188,
}
input2 := []byte{83, 175, 21, 164, 59, 64, 112, 22, 133, 157, 110, 93, 103, 233, 95, 171, 84, 212, 94, 159, 56, 231, 142, 83, 155, 90, 210, 84, 73, 195, 107, 38, 0, 0, 1, 148, 65, 210, 149, 206, 0, 0, 0, 0, 0, 0, 2, 111, 30, 180, 107, 152, 2, 158, 60, 146, 72, 97, 3, 240, 133, 110, 18, 13, 196, 213, 137, 255, 172, 43, 178, 237, 0, 0, 0, 0, 0, 0, 0, 1, 80, 105, 173, 140, 96, 184, 216, 33, 205, 190, 44, 59, 87, 223, 214, 64, 226, 151, 200, 115, 89, 42, 131, 251, 182, 18, 47, 210, 108, 219, 69, 126}

scratchpad := ScratchPadV2{}

hash := XelisHashV2(input, &scratchpad)

expectedHash := [32]byte{
1, 93, 81, 131, 95, 75, 134, 32, 61, 179, 217, 243,
212, 132, 191, 89, 98, 98, 214, 61, 217, 127, 124,
152, 220, 30, 245, 117, 230, 226, 255, 139,
199, 114, 154, 28, 4, 164, 196, 178, 117, 17, 148,
203, 125, 228, 51, 145, 162, 222, 106, 202, 205,
55, 244, 178, 94, 29, 248, 242, 98, 221, 158, 179,
}

expectedHash2 := [32]byte{86, 153, 158, 47, 177, 49, 55, 60, 155, 61, 147, 124, 179, 204, 11, 76, 59, 90, 186, 134, 9, 20, 21, 248, 156, 47, 122, 116, 118, 227, 24, 75}

hash := XelisHashV2(input, &scratchpad)
if hash != expectedHash {
t.Fatalf("incorrect hash: %x, expected: %x", hash, expectedHash)
}

hash = XelisHashV2(input2, &scratchpad)
if hash != expectedHash2 {
t.Fatalf("incorrect hash: %x, expected: %x", hash, expectedHash)
}
t.Logf("%x", hash)
}

func BenchmarkHashV2(b *testing.B) {