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

Community realm. Read the code first. Community realm, deployed by its author. Read the code before you interact or send coins.

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}