An Yggdrasil address miner in Go
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

53 lines
1.4 KiB

  1. package main
  2. import (
  3. "github.com/yggdrasil-network/yggdrasil-go/src/address"
  4. "github.com/yggdrasil-network/yggdrasil-go/src/crypto"
  5. )
  6. // custom function selectors, see crypto_xxx.go
  7. var (
  8. addrForNodeID func(*crypto.NodeID) *address.Address
  9. )
  10. // AddrForNodeID is a variant of Yggdrasil's src/address.AddrForNodeID that
  11. // might be slightly optimized for performance.
  12. //
  13. // This function is a modded variant of address.AddrForNodeID from Yggdrasil.
  14. // See src/address/address.go@78b5f88e4bb734d0dd6a138ff08d34ca39dcaea3
  15. func AddrForNodeID(nid *crypto.NodeID) *address.Address {
  16. // 128 bit address, begins with GetPrefix(), with last bit set to 0
  17. // (indicates an address). Next 7 bits, interpreted as a uint, are the count
  18. // of leading 1s in the NodeID. Leading 1s and first leading 0 of the NodeID
  19. // are truncated off. The rest is appended to the IPv6 address (truncated to
  20. // 128 bits total).
  21. var addr address.Address
  22. temp := make([]byte, 0, len(nid))
  23. done := false
  24. ones := byte(0)
  25. bits := byte(0)
  26. nBits := 0
  27. for idx := 0; idx < 8*len(nid); idx++ {
  28. bit := (nid[idx/8] & (0x80 >> byte(idx%8))) >> byte(7-(idx%8))
  29. if !done && bit != 0 {
  30. ones++
  31. continue
  32. }
  33. if !done && bit == 0 {
  34. done = true
  35. continue
  36. }
  37. bits = (bits << 1) | bit
  38. nBits++
  39. if nBits == 8 {
  40. nBits = 0
  41. temp = append(temp, bits)
  42. }
  43. }
  44. prefix := address.GetPrefix()
  45. copy(addr[:], prefix[:])
  46. addr[len(prefix)] = ones
  47. copy(addr[len(prefix)+1:], temp)
  48. return &addr
  49. }