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)
})
With promises:
const {promise: roughtime} = require('roughtime')
roughtime('roughtime.cloudflare.com').then(result => {
const {midpoint, radius} = result
console.log(midpoint, radius)
})
Or with async/await:
const {promise: roughtime} = require('roughtime')
async function f() {
const {midpoint, radius} = await roughtime('roughtime.cloudflare.com')
console.log(midpoint, radius)
}
f()
roughtime currently knows about two public servers:
roughtime.cloudflare.com
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,])
const options = {
host: 'roughtime.example.com',
port: 1337,
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.