Search Apps Documentation Source Content File Folder Download Copy Actions Download State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

rendezvous.gno

2.25 Kb · 64 lines
 1package wesh
 2
 3import "encoding/binary"
 4
 5// DefaultRotationInterval is weshnet's rendezvous rotation period, in seconds
 6// (rendezvous.DefaultRotationInterval = 24h). The rendezvous point an account
 7// announces on changes once per interval, so an observer who learns one point
 8// does not learn every future one.
 9const DefaultRotationInterval int64 = 86400
10
11// RoundPeriod returns the start of the rotation period containing unixSec.
12// Mirrors weshnet's rendezvous.RoundTimePeriod.
13func RoundPeriod(unixSec, interval int64) int64 {
14	if interval < 0 {
15		interval = -interval
16	}
17	if interval == 0 {
18		panic("wesh: rotation interval must not be zero")
19	}
20	return (unixSec / interval) * interval
21}
22
23// NextPeriod returns the start of the period after the one containing unixSec.
24// Mirrors weshnet's rendezvous.NextTimePeriod.
25func NextPeriod(unixSec, interval int64) int64 {
26	if interval < 0 {
27		interval = -interval
28	}
29	return RoundPeriod(unixSec, interval) + interval
30}
31
32// RendezvousPoint derives the rotating DHT topic an account announces on
33// during the period starting at periodStart.
34//
35// It reproduces weshnet's rendezvous.GenerateRendezvousPointForPeriod exactly:
36//
37//	HMAC-SHA256(key = topic ‖ seed, msg = big-endian uint64(periodStart))
38//
39// For contact requests, weshnet passes the account public key as the topic and
40// the public rendezvous seed as the seed (see swiper.WatchTopic in
41// contact_request_manager.go), which is what [Contact.RendezvousPointAt] does.
42//
43// Deriving this on chain is what makes a published identity checkable: anyone
44// can confirm that the seed in the directory really is the one the account is
45// announcing under, without trusting the directory.
46func RendezvousPoint(topic, seed []byte, periodStart int64) []byte {
47	key := make([]byte, 0, len(topic)+len(seed))
48	key = append(key, topic...)
49	key = append(key, seed...)
50
51	buf := make([]byte, 8)
52	binary.BigEndian.PutUint64(buf, uint64(periodStart))
53
54	return HMACSHA256(key, buf)
55}
56
57// RendezvousPointAt returns the contact's rendezvous point for the rotation
58// period containing unixSec.
59func (c Contact) RendezvousPointAt(unixSec, interval int64) ([]byte, error) {
60	if err := c.Validate(); err != nil {
61		return nil, err
62	}
63	return RendezvousPoint(c.AccountPK, c.Seed, RoundPeriod(unixSec, interval)), nil
64}