From 0d09d1df66bcdbdf34329ef0ce61bb347b69b1b9 Mon Sep 17 00:00:00 2001 From: Elichai Turkel Date: Sat, 6 Nov 2021 21:43:41 +0200 Subject: [PATCH] Add a xoShiRo256PlusPlus implementation --- domain/consensus/utils/pow/xoshiro.go | 37 ++++++++++++++++++++++ domain/consensus/utils/pow/xoshiro_test.go | 17 ++++++++++ 2 files changed, 54 insertions(+) create mode 100644 domain/consensus/utils/pow/xoshiro.go create mode 100644 domain/consensus/utils/pow/xoshiro_test.go diff --git a/domain/consensus/utils/pow/xoshiro.go b/domain/consensus/utils/pow/xoshiro.go new file mode 100644 index 000000000..7775d58a7 --- /dev/null +++ b/domain/consensus/utils/pow/xoshiro.go @@ -0,0 +1,37 @@ +package pow + +import ( + "encoding/binary" + "github.com/kaspanet/kaspad/domain/consensus/model/externalapi" + "math/bits" +) + +type xoShiRo256PlusPlus struct { + s0 uint64 + s1 uint64 + s2 uint64 + s3 uint64 +} + +func newxoShiRo256PlusPlus(hash *externalapi.DomainHash) *xoShiRo256PlusPlus { + hashArray := hash.ByteArray() + return &xoShiRo256PlusPlus{ + s0: binary.LittleEndian.Uint64(hashArray[:8]), + s1: binary.LittleEndian.Uint64(hashArray[8:16]), + s2: binary.LittleEndian.Uint64(hashArray[16:24]), + s3: binary.LittleEndian.Uint64(hashArray[24:32]), + } +} + +func (x *xoShiRo256PlusPlus) Uint64() uint64 { + res := bits.RotateLeft64(x.s0+x.s3, 23) + x.s0 + t := x.s1 << 17 + x.s2 ^= x.s0 + x.s3 ^= x.s1 + x.s1 ^= x.s2 + x.s0 ^= x.s3 + + x.s2 ^= t + x.s3 = bits.RotateLeft64(x.s3, 45) + return res +} diff --git a/domain/consensus/utils/pow/xoshiro_test.go b/domain/consensus/utils/pow/xoshiro_test.go new file mode 100644 index 000000000..6f9815984 --- /dev/null +++ b/domain/consensus/utils/pow/xoshiro_test.go @@ -0,0 +1,17 @@ +package pow + +import "testing" + +// Test vectors are from here: https://github.com/rust-random/rngs/blob/17aa826cc38d3e8408c9489ac859fa9397acd479/rand_xoshiro/src/xoshiro256plusplus.rs#L121 +func TestXoShiRo256PlusPlus_Uint64(t *testing.T) { + state := xoShiRo256PlusPlus{1, 2, 3, 4} + expected := []uint64{41943041, 58720359, 3588806011781223, 3591011842654386, + 9228616714210784205, 9973669472204895162, 14011001112246962877, + 12406186145184390807, 15849039046786891736, 10450023813501588000} + for _, ex := range expected { + val := state.Uint64() + if val != ex { + t.Errorf("expected: %d, found: %d", ex, val) + } + } +}