github.com/mit-dci/lit@v0.0.0-20221102210550-8c3d3b49f2ce/shortaddr/shortadr.go (about)

     1  package shortadr
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/binary"
     6  
     7  	"github.com/mit-dci/lit/crypto/fastsha256"
     8  )
     9  
    10  /*
    11  initial short address code.  You can spin up a bunch of worker goroutines
    12  (1 per core?)  and give them different IDs.  They will try sequential nonces,
    13  and report back when they find nonces that have more work than the minWork they're
    14  given.  They'll keep reporting better and better nonces until either they loop
    15  around the uint64 (which will take a long time, and should be avoided), or they're
    16  given a kill command via the stop channel.
    17  */
    18  
    19  // AdrWorker is a gorouting that looks for a short hash.
    20  // pub is the pub key to work on.  ID & Nonce is the nonce to start at.
    21  // bestNonce is a channel that returns the best nonce each time one is found
    22  // stop is a channel that kills this worker
    23  func AdrWorker(
    24  	pub [33]byte, id, nonce uint64, bestBits uint8,
    25  	bestNonce chan uint64, stop chan bool) {
    26  
    27  	for {
    28  		select { // select here so we don't block on an unrequested mblock
    29  		case _ = <-stop: // got order to stop
    30  			return
    31  		default:
    32  			hash := DoOneTry(pub, id, nonce)
    33  			bits := CheckWork(hash)
    34  			if bits > bestBits {
    35  				bestBits = bits
    36  				bestNonce <- nonce
    37  			}
    38  		}
    39  		nonce++
    40  	}
    41  }
    42  
    43  // doOneTry is a single hash attempt with a key and nonce
    44  func DoOneTry(key [33]byte, id, nonce uint64) (hash [20]byte) {
    45  	var buf bytes.Buffer
    46  	buf.Write(key[:])
    47  	binary.Write(&buf, binary.BigEndian, id)
    48  	binary.Write(&buf, binary.BigEndian, nonce)
    49  
    50  	shaoutput := fastsha256.Sum256(buf.Bytes())
    51  	copy(hash[:], shaoutput[:20])
    52  	return
    53  }
    54  
    55  // CheckWork returns the number of leading 0 bits
    56  // make it not crash with all zero hash arguments
    57  func CheckWork(hash [20]byte) (i uint8) {
    58  	for ; i < 160 && (hash[i/8]>>(7-(i%8)))&1 == 0; i++ {
    59  	}
    60  	return
    61  }