Skip to content

Roughtime client for Node.js. Roughtime provides secure time synchronisation.

License

Notifications You must be signed in to change notification settings

bnoordhuis/node-roughtime

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

roughtime

This module implements a Roughtime client for Node.js v6.x and up.

Roughtime?

Roughtime is a project that aims to provide secure time synchronisation.

With NTP, a third party can intercept and modify replies from the server. The reply you get is not necessarily and certainly not provably what the server sent.

Roughtime replies cannot be forged: they are cryptographically signed using Ed25519. Clients can also create audit trails to help weed out misbehaving servers (another common problem with NTP.)

See the Roughtime homepage for more information.

Concepts

  • Midpoint is the server's idea of "now" relative to the UNIX epoch, expressed in microseconds.

  • Radius is the server's uncertainty about the midpoint, also expressed in microseconds.

The server asserts that the true time is within midpoint - radius/2 and midpoint + radius/2.

Return-trip network latency is not accounted for. Expect that to be on the order of several milliseconds.

Leap seconds are smeared out over the course of a day.

Usage

Good ol' callback-style:

const roughtime = require('roughtime')

roughtime('roughtime.cloudflare.com', (err, result) => {
	if (err) throw err
	const {midpoint, radius} = result
	console.log(midpoint, radius) // ex. "1537907399109000 1000000"
	console.log(new Date(midpoint / 1e3)) // ex. "2018-09-25T20:29:59.109Z"
})

With promises:

const {promise: roughtime} = require('roughtime')

roughtime('roughtime.cloudflare.com').then(result => {
	const {midpoint, radius} = result
	console.log(midpoint, radius) // ex. "1537907399109000 1000000"
})

Or with async/await:

const {promise: roughtime} = require('roughtime')

async function f() {
	const {midpoint, radius} = await roughtime('roughtime.cloudflare.com')
	console.log(midpoint, radius) // ex. "1537907399109000 1000000"
}

f() // no top-level await yet in Node.js

roughtime currently knows about two public servers:

  1. roughtime.cloudflare.com
  2. roughtime.sandbox.google.com

To query other servers, provide the host name and optionally the port number, and include the server's public key as a Buffer or Uint8Array:

const roughtime = require('roughtime')

const pubkey = Uint8Array.from([0,0,0,0,/*...*/]) // must be 32 bytes

const options = {
	host: 'roughtime.example.com',
	port: 1337, // default is 2002
	pubkey: pubkey,
}

roughtime(options, (err, result) => {
	// ...
})

If you want to plug in your own nonce or UDP socket, you can: the options are called .nonce and .socket respectively. The nonce must be a 64 byte Buffer or Uint8Array:

const roughtime = require('roughtime')
const {randomBytes} = require('crypto')

const host = 'roughtime.cloudflare.com'
const nonce = randomBytes(64)
const options = {host, nonce}

roughtime(options, (err, result) => {
	// ...
})

Known bugs

  • Auditing is not implemented. The ecosystem isn't large enough yet to make it practical.

  • Merkle tree verification has only been lightly tested. I have yet to see a server in the wild return a reply that contains one.

About

Roughtime client for Node.js. Roughtime provides secure time synchronisation.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published