idhash.go raw

   1  package types
   2  
   3  import (
   4  	"encoding/base64"
   5  	"io"
   6  
   7  	"next.orly.dev/pkg/lol/chk"
   8  	"next.orly.dev/pkg/lol/errorf"
   9  	"github.com/minio/sha256-simd"
  10  	"next.orly.dev/pkg/nostr/encoders/hex"
  11  )
  12  
  13  const IdHashLen = 8
  14  
  15  type IdHash struct{ val [IdHashLen]byte }
  16  
  17  func (i *IdHash) Set(idh []byte) {
  18  	if len(idh) != IdHashLen {
  19  		panic("invalid IdHash length")
  20  	}
  21  	copy(i.val[:], idh)
  22  }
  23  
  24  func (i *IdHash) FromId(id []byte) (err error) {
  25  	if len(id) != sha256.Size {
  26  		err = errorf.E(
  27  			"FromId: invalid ID length, got %d require %d (data=%x)", len(id),
  28  			sha256.Size, id,
  29  		)
  30  		return
  31  	}
  32  	idh := sha256.Sum256(id)
  33  	copy(i.val[:], idh[:IdHashLen])
  34  	return
  35  }
  36  
  37  func (i *IdHash) FromIdBase64(idb64 string) (err error) {
  38  	// Decode the base64 string
  39  	decoded, err := base64.RawURLEncoding.DecodeString(idb64)
  40  	if chk.E(err) {
  41  		return
  42  	}
  43  
  44  	// Check if the decoded ID has the correct length
  45  	if len(decoded) != sha256.Size {
  46  		err = errorf.E(
  47  			"FromIdBase64: invalid ID length, got %d require %d", len(decoded),
  48  			sha256.Size,
  49  		)
  50  		return
  51  	}
  52  
  53  	// Hash the decoded ID and take the first IdHashLen bytes
  54  	idh := sha256.Sum256(decoded)
  55  	copy(i.val[:], idh[:IdHashLen])
  56  	return
  57  }
  58  
  59  func (i *IdHash) FromIdHex(idh string) (err error) {
  60  	var id []byte
  61  	if id, err = hex.Dec(idh); chk.E(err) {
  62  		return
  63  	}
  64  	if len(id) != sha256.Size {
  65  		err = errorf.E(
  66  			"FromIdHex: invalid ID length, got %d require %d", len(id),
  67  			sha256.Size,
  68  		)
  69  		return
  70  	}
  71  	h := sha256.Sum256(id)
  72  	copy(i.val[:], h[:IdHashLen])
  73  	return
  74  
  75  }
  76  
  77  func (i *IdHash) Bytes() (b []byte) { return i.val[:] }
  78  
  79  func (i *IdHash) MarshalWrite(w io.Writer) (err error) {
  80  	_, err = w.Write(i.val[:])
  81  	return
  82  }
  83  
  84  func (i *IdHash) UnmarshalRead(r io.Reader) (err error) {
  85  	_, err = r.Read(i.val[:])
  86  	return
  87  }
  88