protocol

package
v1.2.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 7, 2026 License: BSD-2-Clause Imports: 10 Imported by: 0

Documentation

Overview

Package protocol implements the Roughtime wire protocol for both server and client use.

Supported versions:

Google-Roughtime                        (no version number)
draft-ietf-ntp-roughtime-00             (unsupported; predates VER)
draft-ietf-ntp-roughtime-01             0x80000001
draft-ietf-ntp-roughtime-02             0x80000002
draft-ietf-ntp-roughtime-03             0x80000003
draft-ietf-ntp-roughtime-04             0x80000004
draft-ietf-ntp-roughtime-05             0x80000005
draft-ietf-ntp-roughtime-06             0x80000006
draft-ietf-ntp-roughtime-07             0x80000007
draft-ietf-ntp-roughtime-08             0x80000008
draft-ietf-ntp-roughtime-09             0x80000009
draft-ietf-ntp-roughtime-10             0x8000000a
draft-ietf-ntp-roughtime-11             0x8000000b
draft-ietf-ntp-roughtime-12             0x8000000c
draft-ietf-ntp-roughtime-13             0x8000000c
draft-ietf-ntp-roughtime-14             0x8000000c
draft-ietf-ntp-roughtime-15             0x8000000c
draft-ietf-ntp-roughtime-16             0x8000000c
draft-ietf-ntp-roughtime-17             0x8000000c
draft-ietf-ntp-roughtime-18             0x8000000c
draft-ietf-ntp-roughtime-19             0x8000000c

Index

Constants

View Source
const (
	TagSIG  uint32 = 0x00474953 // SIG\0
	TagVER  uint32 = 0x00524556 // VER\0
	TagSRV  uint32 = 0x00565253 // SRV\0
	TagNONC uint32 = 0x434e4f4e // NONC
	TagDELE uint32 = 0x454c4544 // DELE
	TagTYPE uint32 = 0x45505954 // TYPE
	TagPATH uint32 = 0x48544150 // PATH
	TagRADI uint32 = 0x49444152 // RADI
	TagPUBK uint32 = 0x4b425550 // PUBK
	TagMIDP uint32 = 0x5044494d // MIDP
	TagSREP uint32 = 0x50455253 // SREP
	TagVERS uint32 = 0x53524556 // VERS
	TagROOT uint32 = 0x544f4f52 // ROOT
	TagCERT uint32 = 0x54524543 // CERT
	TagMINT uint32 = 0x544e494d // MINT
	TagMAXT uint32 = 0x5458414d // MAXT
	TagINDX uint32 = 0x58444e49 // INDX
	TagZZZZ uint32 = 0x5a5a5a5a // ZZZZ (client padding, drafts 08+)
	TagPAD  uint32 = 0xff444150 // PAD\xff (Google-Roughtime client padding)

)

Tag constants from the IANA Roughtime tag registry. These identify fields in Roughtime wire-format messages.

Variables

This section is empty.

Functions

func CreateReplies

func CreateReplies(ver Version, requests []Request, midpoint time.Time, radius time.Duration, cert *Certificate) ([][]byte, error)

CreateReplies builds signed responses for a batch of requests.

func CreateRequest added in v1.1.0

func CreateRequest(versions []Version, entropy io.Reader) (nonce, request []byte, err error)

CreateRequest builds a Roughtime request for the given version preferences. For Google-Roughtime, pass a single-element slice containing VersionGoogle. For IETF versions, pass one or more version constants in preference order.

The returned nonce is needed to verify the server's reply. The returned request is a complete UDP payload ready to send.

func Decode

func Decode(data []byte) (map[uint32][]byte, error)

Decode parses a Roughtime message into a tag-value map. The returned byte slices are sub-slices of data and share its underlying memory.

func DecodeRadius added in v1.1.0

func DecodeRadius(ver Version, buf []byte) (time.Duration, error)

DecodeRadius converts a 4-byte wire-format RADI value to a time.Duration using the encoding rules for the given version: microseconds for Google-Roughtime and drafts 01–07, or seconds for drafts 08+.

func DecodeTimestamp added in v1.1.0

func DecodeTimestamp(ver Version, buf []byte) (time.Time, error)

DecodeTimestamp converts an 8-byte wire-format timestamp to a time.Time using the encoding rules for the given version: Unix microseconds for Google-Roughtime, MJD microseconds for drafts 01–07, or Unix seconds for drafts 08+.

func Encode

func Encode(msg map[uint32][]byte) ([]byte, error)

Encode serializes a tag-value map into a Roughtime message. All values must have lengths that are multiples of 4 bytes. Tags are emitted in ascending numeric order as required by the wire format.

func NonceSize added in v1.1.0

func NonceSize(ver Version) int

NonceSize returns the nonce length in bytes for a version: 64 for Google-Roughtime and drafts 01–04, 32 for drafts 05+.

func UnwrapPacket

func UnwrapPacket(pkt []byte) ([]byte, error)

UnwrapPacket validates and strips the 12-byte ROUGHTIM header.

func VerifyReply added in v1.1.0

func VerifyReply(versions []Version, reply, rootPK, nonce, requestBytes []byte) (midpoint time.Time, radius time.Duration, err error)

VerifyReply authenticates a server response and returns the midpoint time and uncertainty radius. It verifies the delegation certificate against rootPK, verifies the signed response against the online key, checks the Merkle proof for nonce inclusion, and validates that the midpoint falls within the delegation window.

The versions slice must contain the same preferences used in CreateRequest. For Google-Roughtime, pass VersionGoogle.

For drafts 12+, the Merkle tree leaf is computed over the full request packet rather than just the nonce. Pass the complete request bytes (as returned by CreateRequest) as requestBytes. For earlier versions, requestBytes is ignored and may be nil.

func WrapPacket

func WrapPacket(message []byte) []byte

WrapPacket prepends the 12-byte ROUGHTIM header (8-byte magic + 4-byte message length).

Types

type Certificate

type Certificate struct {
	// contains filtered or unexported fields
}

Certificate holds a pre-signed online delegation for each wire format group. The CERT bytes are computed once at construction and reused across requests.

func NewCertificate

func NewCertificate(mint, maxt time.Time, onlineSK, rootSK ed25519.PrivateKey) (*Certificate, error)

NewCertificate creates and signs an online delegation certificate. The CERT bytes for every wire format group are pre-computed and cached.

type Request

type Request struct {
	Nonce     []byte    // 32 bytes (IETF drafts 05+) or 64 bytes (Google, drafts 01–04)
	Versions  []Version // from VER tag; empty for Google/draft-00
	SRV       []byte    // optional; nil if absent
	HasType   bool      // true when request contains TYPE=0 (drafts 14+)
	RawPacket []byte    // complete UDP payload for Merkle leaf (drafts 12+)
}

Request holds the parsed fields of a client request.

func ParseRequest

func ParseRequest(raw []byte) (*Request, error)

ParseRequest auto-detects Google vs IETF framing and extracts request fields. The Nonce and SRV fields are sub-slices of raw and share its memory.

type Version

type Version uint32

Version is a Roughtime protocol version number. The zero value represents Google-Roughtime, which does not use a VER tag on the wire.

const (
	VersionGoogle  Version = 0          // Google-Roughtime (no VER tag)
	VersionDraft01 Version = 0x80000001 // draft-ietf-ntp-roughtime-01
	VersionDraft02 Version = 0x80000002 // draft-ietf-ntp-roughtime-02
	VersionDraft03 Version = 0x80000003 // draft-ietf-ntp-roughtime-03
	VersionDraft04 Version = 0x80000004 // draft-ietf-ntp-roughtime-04
	VersionDraft05 Version = 0x80000005 // draft-ietf-ntp-roughtime-05
	VersionDraft06 Version = 0x80000006 // draft-ietf-ntp-roughtime-06
	VersionDraft07 Version = 0x80000007 // draft-ietf-ntp-roughtime-07
	VersionDraft08 Version = 0x80000008 // draft-ietf-ntp-roughtime-08
	VersionDraft09 Version = 0x80000009 // draft-ietf-ntp-roughtime-09
	VersionDraft10 Version = 0x8000000a // draft-ietf-ntp-roughtime-10
	VersionDraft11 Version = 0x8000000b // draft-ietf-ntp-roughtime-11
	VersionDraft12 Version = 0x8000000c // draft-ietf-ntp-roughtime-12 through 19
)

func ExtractVersion added in v1.1.0

func ExtractVersion(reply []byte) (Version, bool)

ExtractVersion returns the negotiated version from a raw server reply.

func SelectVersion

func SelectVersion(clientVersions []Version, nonceLen int) (Version, error)

SelectVersion picks the best mutually supported version. For Google-Roughtime clients (no VER tag, 64-byte nonce), pass an empty clientVersions slice.

func SupportedVersions

func SupportedVersions() []Version

SupportedVersions returns all IETF version numbers in ascending order.

func (Version) ShortString added in v1.1.0

func (v Version) ShortString() string

ShortString returns a compact version label (e.g. "Google", "draft-08", "draft-12"). For unknown values it returns the hex wire number.

func (Version) String added in v1.1.0

func (v Version) String() string

String returns the IETF draft name for known versions (e.g. "draft-ietf-ntp-roughtime-08") or a hex representation for unknown values. Drafts 12–19 share wire version 0x8000000c; String reports "draft-ietf-ntp-roughtime-12" since the wire format cannot distinguish later revisions.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL