git.gammaspectra.live/P2Pool/consensus/v3@v3.8.0/p2pool/p2p/challenge.go (about)

     1  package p2p
     2  
     3  import (
     4  	"crypto/rand"
     5  	"encoding/binary"
     6  	"git.gammaspectra.live/P2Pool/consensus/v3/monero/crypto"
     7  	"git.gammaspectra.live/P2Pool/consensus/v3/types"
     8  	"math/bits"
     9  	"sync/atomic"
    10  	"unsafe"
    11  )
    12  
    13  const HandshakeChallengeSize = 8
    14  const HandshakeChallengeDifficulty = 10000
    15  
    16  type HandshakeChallenge [HandshakeChallengeSize]byte
    17  
    18  func FindChallengeSolution(challenge HandshakeChallenge, consensusId types.Hash, stop *atomic.Bool) (solution uint64, hash types.Hash, ok bool) {
    19  
    20  	var buf [HandshakeChallengeSize*2 + types.HashSize]byte
    21  	copy(buf[:], challenge[:])
    22  	copy(buf[HandshakeChallengeSize:], consensusId[:])
    23  	var salt uint64
    24  
    25  	var saltSlice [int(unsafe.Sizeof(salt))]byte
    26  	_, _ = rand.Read(saltSlice[:])
    27  	salt = binary.LittleEndian.Uint64(saltSlice[:])
    28  
    29  	h := crypto.GetKeccak256Hasher()
    30  	defer crypto.PutKeccak256Hasher(h)
    31  
    32  	var sum types.Hash
    33  
    34  	for {
    35  		h.Reset()
    36  		binary.LittleEndian.PutUint64(buf[types.HashSize+HandshakeChallengeSize:], salt)
    37  		_, _ = h.Write(buf[:])
    38  		crypto.HashFastSum(h, sum[:])
    39  
    40  		//check if we have been asked to stop
    41  		if stop.Load() {
    42  			return salt, sum, false
    43  		}
    44  
    45  		if hi, _ := bits.Mul64(binary.LittleEndian.Uint64(sum[len(sum)-int(unsafe.Sizeof(uint64(0))):]), HandshakeChallengeDifficulty); hi == 0 {
    46  			//found solution
    47  			return salt, sum, true
    48  		}
    49  
    50  		salt++
    51  	}
    52  }
    53  
    54  func CalculateChallengeHash(challenge HandshakeChallenge, consensusId types.Hash, solution uint64) (hash types.Hash, ok bool) {
    55  	hash = crypto.PooledKeccak256(challenge[:], consensusId[:], binary.LittleEndian.AppendUint64(nil, solution))
    56  	hi, _ := bits.Mul64(binary.LittleEndian.Uint64(hash[types.HashSize-int(unsafe.Sizeof(uint64(0))):]), HandshakeChallengeDifficulty)
    57  	return hash, hi == 0
    58  }