New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

noise-protocol

Package Overview
Dependencies
Maintainers
1
Versions
10
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

noise-protocol - npm Package Compare versions

Comparing version 3.0.1 to 3.0.2

.github/workflows/npm.yml

201

cipher-state.js

@@ -5,126 +5,127 @@ /* eslint-disable camelcase */

var assert = require('nanoassert')
var cipher = require('./cipher')
const assert = require('nanoassert')
var STATELEN = cipher.KEYLEN + cipher.NONCELEN
var NONCELEN = cipher.NONCELEN
var MACLEN = cipher.MACLEN
module.exports = ({ cipher }) => {
const STATELEN = cipher.KEYLEN + cipher.NONCELEN
const NONCELEN = cipher.NONCELEN
const MACLEN = cipher.MACLEN
module.exports = {
STATELEN,
NONCELEN,
MACLEN,
initializeKey,
hasKey,
setNonce,
encryptWithAd,
decryptWithAd,
rekey
}
const KEY_BEGIN = 0
const KEY_END = cipher.KEYLEN
const NONCE_BEGIN = KEY_END
const NONCE_END = NONCE_BEGIN + cipher.NONCELEN
var KEY_BEGIN = 0
var KEY_END = cipher.KEYLEN
var NONCE_BEGIN = KEY_END
var NONCE_END = NONCE_BEGIN + cipher.NONCELEN
function initializeKey (state, key) {
assert(state.byteLength === STATELEN)
assert(key == null ? true : key.byteLength === cipher.KEYLEN)
function initializeKey (state, key) {
assert(state.byteLength === STATELEN)
assert(key == null ? true : key.byteLength === cipher.KEYLEN)
if (key == null) {
sodium_memzero(state.subarray(KEY_BEGIN, KEY_END))
return
}
if (key == null) {
sodium_memzero(state.subarray(KEY_BEGIN, KEY_END))
return
state.set(key)
sodium_memzero(state.subarray(NONCE_BEGIN, NONCE_END))
}
state.set(key)
sodium_memzero(state.subarray(NONCE_BEGIN, NONCE_END))
}
function hasKey (state) {
assert(state.byteLength === STATELEN)
const k = state.subarray(KEY_BEGIN, KEY_END)
return sodium_is_zero(k) === false
}
function hasKey (state) {
assert(state.byteLength === STATELEN)
var k = state.subarray(KEY_BEGIN, KEY_END)
return sodium_is_zero(k) === false
}
function setNonce (state, nonce) {
assert(state.byteLength === STATELEN)
assert(nonce.byteLength === NONCELEN)
function setNonce (state, nonce) {
assert(state.byteLength === STATELEN)
assert(nonce.byteLength === NONCELEN)
state.set(nonce, NONCE_BEGIN)
}
state.set(nonce, NONCE_BEGIN)
}
const maxnonce = new Uint8Array(8).fill(0xff)
function encryptWithAd (state, out, ad, plaintext) {
assert(state.byteLength === STATELEN)
assert(out.byteLength != null)
assert(plaintext.byteLength != null)
var maxnonce = new Uint8Array(8).fill(0xff)
function encryptWithAd (state, out, ad, plaintext) {
assert(state.byteLength === STATELEN)
assert(out.byteLength != null)
assert(plaintext.byteLength != null)
const n = state.subarray(NONCE_BEGIN, NONCE_END)
if (sodium_memcmp(n, maxnonce)) throw new Error('Nonce overflow')
var n = state.subarray(NONCE_BEGIN, NONCE_END)
if (sodium_memcmp(n, maxnonce)) throw new Error('Nonce overflow')
if (hasKey(state) === false) {
out.set(plaintext)
encryptWithAd.bytesRead = plaintext.byteLength
encryptWithAd.bytesWritten = encryptWithAd.bytesRead
return
}
if (hasKey(state) === false) {
out.set(plaintext)
encryptWithAd.bytesRead = plaintext.byteLength
encryptWithAd.bytesWritten = encryptWithAd.bytesRead
return
const k = state.subarray(KEY_BEGIN, KEY_END)
cipher.encrypt(
out,
k,
n,
ad,
plaintext
)
encryptWithAd.bytesRead = cipher.encrypt.bytesRead
encryptWithAd.bytesWritten = cipher.encrypt.bytesWritten
sodium_increment(n)
}
encryptWithAd.bytesRead = 0
encryptWithAd.bytesWritten = 0
var k = state.subarray(KEY_BEGIN, KEY_END)
function decryptWithAd (state, out, ad, ciphertext) {
assert(state.byteLength === STATELEN)
assert(out.byteLength != null)
assert(ciphertext.byteLength != null)
cipher.encrypt(
out,
k,
n,
ad,
plaintext
)
encryptWithAd.bytesRead = cipher.encrypt.bytesRead
encryptWithAd.bytesWritten = cipher.encrypt.bytesWritten
const n = state.subarray(NONCE_BEGIN, NONCE_END)
if (sodium_memcmp(n, maxnonce)) throw new Error('Nonce overflow')
sodium_increment(n)
}
encryptWithAd.bytesRead = 0
encryptWithAd.bytesWritten = 0
if (hasKey(state) === false) {
out.set(ciphertext)
decryptWithAd.bytesRead = ciphertext.byteLength
decryptWithAd.bytesWritten = decryptWithAd.bytesRead
return
}
function decryptWithAd (state, out, ad, ciphertext) {
assert(state.byteLength === STATELEN)
assert(out.byteLength != null)
assert(ciphertext.byteLength != null)
const k = state.subarray(KEY_BEGIN, KEY_END)
var n = state.subarray(NONCE_BEGIN, NONCE_END)
if (sodium_memcmp(n, maxnonce)) throw new Error('Nonce overflow')
cipher.decrypt(
out,
k,
n,
ad,
ciphertext
)
decryptWithAd.bytesRead = cipher.decrypt.bytesRead
decryptWithAd.bytesWritten = cipher.decrypt.bytesWritten
if (hasKey(state) === false) {
out.set(ciphertext)
decryptWithAd.bytesRead = ciphertext.byteLength
decryptWithAd.bytesWritten = decryptWithAd.bytesRead
return
sodium_increment(n)
}
decryptWithAd.bytesRead = 0
decryptWithAd.bytesWritten = 0
var k = state.subarray(KEY_BEGIN, KEY_END)
function rekey (state) {
assert(state.byteLength === STATELEN)
cipher.decrypt(
out,
k,
n,
ad,
ciphertext
)
decryptWithAd.bytesRead = cipher.decrypt.bytesRead
decryptWithAd.bytesWritten = cipher.decrypt.bytesWritten
const k = state.subarray(KEY_BEGIN, KEY_END)
cipher.rekey(k, k)
rekey.bytesRead = cipher.rekey.bytesRead
rekey.bytesWritten = cipher.rekey.bytesWritten
}
rekey.bytesRead = 0
rekey.bytesWritten = 0
sodium_increment(n)
return {
STATELEN,
NONCELEN,
MACLEN,
initializeKey,
hasKey,
setNonce,
encryptWithAd,
decryptWithAd,
rekey
}
}
decryptWithAd.bytesRead = 0
decryptWithAd.bytesWritten = 0
function rekey (state) {
assert(state.byteLength === STATELEN)
var k = state.subarray(KEY_BEGIN, KEY_END)
cipher.rekey(k, k)
rekey.bytesRead = cipher.rekey.bytesRead
rekey.bytesWritten = cipher.rekey.bytesWritten
}
rekey.bytesRead = 0
rekey.bytesWritten = 0

@@ -11,8 +11,13 @@ /* eslint-disable camelcase */

var assert = require('nanoassert')
const assert = require('nanoassert')
var KEYLEN = 32
var NONCELEN = 8
var MACLEN = 16
const KEYLEN = 32
const NONCELEN = 8
const MACLEN = 16
const ALG = 'ChaChaPoly'
const maxnonce = new Uint8Array(8).fill(0xff)
const zerolen = new Uint8Array(0)
const zeros = new Uint8Array(32)
assert(crypto_aead_chacha20poly1305_ietf_KEYBYTES === KEYLEN)

@@ -23,12 +28,13 @@ // 16 bytes are cut off in the following functions

module.exports = {
module.exports = () => ({
KEYLEN,
NONCELEN,
MACLEN,
ALG,
encrypt,
decrypt,
rekey
}
})
var ElongatedNonce = sodium_malloc(crypto_aead_chacha20poly1305_ietf_NPUBBYTES)
const ElongatedNonce = sodium_malloc(crypto_aead_chacha20poly1305_ietf_NPUBBYTES)
function encrypt (out, k, n, ad, plaintext) {

@@ -68,7 +74,3 @@ assert(out.byteLength >= plaintext.byteLength + MACLEN, 'output buffer must be at least plaintext plus MACLEN bytes long')

var maxnonce = new Uint8Array(8).fill(0xff)
var zerolen = new Uint8Array(0)
var zeros = new Uint8Array(32)
var IntermediateKey = sodium_malloc(KEYLEN + MACLEN)
const IntermediateKey = sodium_malloc(KEYLEN + MACLEN)
sodium_memzero(IntermediateKey)

@@ -75,0 +77,0 @@ function rekey (out, k) {

@@ -5,10 +5,11 @@ /* eslint-disable camelcase */

var assert = require('nanoassert')
const assert = require('nanoassert')
var DHLEN = crypto_scalarmult_BYTES
var PKLEN = crypto_scalarmult_BYTES
var SKLEN = crypto_scalarmult_SCALARBYTES
var SEEDLEN = crypto_kx_SEEDBYTES
const DHLEN = crypto_scalarmult_BYTES
const PKLEN = crypto_scalarmult_BYTES
const SKLEN = crypto_scalarmult_SCALARBYTES
const SEEDLEN = crypto_kx_SEEDBYTES
const ALG = '25519'
module.exports = {
module.exports = () => ({
DHLEN,

@@ -18,6 +19,7 @@ PKLEN,

SEEDLEN,
ALG,
generateKeypair,
generateSeedKeypair,
dh
}
})

@@ -24,0 +26,0 @@ function generateKeypair (pk, sk) {

@@ -1,14 +0,14 @@

var noise = require('.')
const noise = require('./index2')
var sClient = noise.keygen()
var sServer = noise.keygen()
const sClient = noise.keygen()
const sServer = noise.keygen()
var client = noise.initialize('KK', true, Buffer.alloc(0), sClient, null, sServer.publicKey)
var server = noise.initialize('KK', false, Buffer.alloc(0), sServer, null, sClient.publicKey)
const client = noise.initialize('KK', true, Buffer.alloc(0), sClient, null, sServer.publicKey)
const server = noise.initialize('KK', false, Buffer.alloc(0), sServer, null, sClient.publicKey)
var clientTx = Buffer.alloc(128)
var serverTx = Buffer.alloc(128)
const clientTx = Buffer.alloc(128)
const serverTx = Buffer.alloc(128)
var clientRx = Buffer.alloc(128)
var serverRx = Buffer.alloc(128)
const clientRx = Buffer.alloc(128)
const serverRx = Buffer.alloc(128)

@@ -20,4 +20,4 @@ // -> e, es, ss

// <- e, ee, se
var serverSplit = noise.writeMessage(server, Buffer.alloc(0), serverTx)
var clientSplit = noise.readMessage(client, serverTx.subarray(0, noise.writeMessage.bytes), clientRx)
const serverSplit = noise.writeMessage(server, Buffer.alloc(0), serverTx)
const clientSplit = noise.readMessage(client, serverTx.subarray(0, noise.writeMessage.bytes), clientRx)

@@ -24,0 +24,0 @@ noise.destroy(client)

@@ -5,35 +5,310 @@ /* eslint-disable camelcase */

const clone = require('clone')
const symmetricState = require('./symmetric-state')
const cipherState = require('./cipher-state')
const dh = require('./dh')
const PKLEN = dh.PKLEN
const SKLEN = dh.SKLEN
function createHandshake ({ dh, hash, cipher, symmetricState, cipherState }) {
const DhResult = sodium_malloc(dh.DHLEN)
module.exports = Object.freeze({
initialize,
writeMessage,
readMessage,
destroy,
keygen,
seedKeygen,
SKLEN,
PKLEN
})
function HandshakeState () {
this.symmetricState = sodium_malloc(symmetricState.STATELEN)
function HandshakeState () {
this.symmetricState = sodium_malloc(symmetricState.STATELEN)
this.initiator = null
this.initiator = null
this.spk = null
this.ssk = null
this.spk = null
this.ssk = null
this.epk = null
this.esk = null
this.epk = null
this.esk = null
this.rs = null
this.re = null
this.rs = null
this.re = null
this.messagePatterns = null
}
this.messagePatterns = null
function initialize (handshakePattern, initiator, prologue, s, e, rs, re) {
assert(Object.keys(PATTERNS).includes(handshakePattern), 'Unsupported handshake pattern')
assert(typeof initiator === 'boolean', 'Initiator must be a boolean')
assert(prologue.byteLength != null, 'prolouge must be a Buffer')
assert(e == null ? true : e.publicKey.byteLength === dh.PKLEN, `e.publicKey must be ${dh.PKLEN} bytes`)
assert(e == null ? true : e.secretKey.byteLength === dh.SKLEN, `e.secretKey must be ${dh.SKLEN} bytes`)
assert(rs == null ? true : rs.byteLength === dh.PKLEN, `rs must be ${dh.PKLEN} bytes`)
assert(re == null ? true : re.byteLength === dh.PKLEN, `re must be ${dh.PKLEN} bytes`)
const state = new HandshakeState()
const protocolName = Uint8Array.from(`Noise_${handshakePattern}_${dh.ALG}_${cipher.ALG}_${hash.ALG}`, toCharCode)
symmetricState.initializeSymmetric(state.symmetricState, protocolName)
symmetricState.mixHash(state.symmetricState, prologue)
state.role = initiator === true ? INITIATOR : RESPONDER
if (s != null) {
assert(s.publicKey.byteLength === dh.PKLEN, `s.publicKey must be ${dh.PKLEN} bytes`)
assert(s.secretKey.byteLength === dh.SKLEN, `s.secretKey must be ${dh.SKLEN} bytes`)
state.spk = sodiumBufferCopy(s.publicKey)
state.ssk = sodiumBufferCopy(s.secretKey)
}
if (e != null) {
assert(e.publicKey.byteLength === dh.PKLEN)
assert(e.secretKey.byteLength === dh.SKLEN)
state.epk = sodiumBufferCopy(e.publicKey)
state.esk = sodiumBufferCopy(e.secretKey)
}
if (rs != null) {
assert(rs.byteLength === dh.PKLEN)
state.rs = sodiumBufferCopy(rs)
}
if (re != null) {
assert(re.byteLength === dh.PKLEN)
state.re = sodiumBufferCopy(re)
}
// hashing
const pat = PATTERNS[handshakePattern]
for (const pattern of clone(pat.premessages)) {
const patternRole = pattern.shift()
for (const token of pattern) {
switch (token) {
case TOK_E:
assert(state.role === patternRole ? state.epk.byteLength != null : state.re.byteLength != null)
symmetricState.mixHash(state.symmetricState, state.role === patternRole ? state.epk : state.re)
break
case TOK_S:
assert(state.role === patternRole ? state.spk.byteLength != null : state.rs.byteLength != null)
symmetricState.mixHash(state.symmetricState, state.role === patternRole ? state.spk : state.rs)
break
default:
throw new Error('Invalid premessage pattern')
}
}
}
state.messagePatterns = clone(pat.messagePatterns)
assert(state.messagePatterns.filter(p => p[0] === INITIATOR).some(p => p.includes(TOK_S))
? (state.spk !== null && state.ssk !== null)
: true, // Default if none is found
'This handshake pattern requires a static keypair')
return state
}
function writeMessage (state, payload, messageBuffer) {
assert(state instanceof HandshakeState)
assert(payload.byteLength != null)
assert(messageBuffer.byteLength != null)
const mpat = state.messagePatterns.shift()
let moffset = 0
assert(mpat != null)
assert(state.role === mpat.shift())
for (const token of mpat) {
switch (token) {
case TOK_E:
assert(state.epk == null)
assert(state.esk == null)
state.epk = sodium_malloc(dh.PKLEN)
state.esk = sodium_malloc(dh.SKLEN)
dh.generateKeypair(state.epk, state.esk)
messageBuffer.set(state.epk, moffset)
moffset += state.epk.byteLength
symmetricState.mixHash(state.symmetricState, state.epk)
break
case TOK_S:
assert(state.spk.byteLength === dh.PKLEN)
symmetricState.encryptAndHash(state.symmetricState, messageBuffer.subarray(moffset), state.spk)
moffset += symmetricState.encryptAndHash.bytesWritten
break
case TOK_EE:
dh.dh(DhResult, state.esk, state.re)
symmetricState.mixKey(state.symmetricState, DhResult)
sodium_memzero(DhResult)
break
case TOK_ES:
if (state.role === INITIATOR) dh.dh(DhResult, state.esk, state.rs)
else dh.dh(DhResult, state.ssk, state.re)
symmetricState.mixKey(state.symmetricState, DhResult)
sodium_memzero(DhResult)
break
case TOK_SE:
if (state.role === INITIATOR) dh.dh(DhResult, state.ssk, state.re)
else dh.dh(DhResult, state.esk, state.rs)
symmetricState.mixKey(state.symmetricState, DhResult)
sodium_memzero(DhResult)
break
case TOK_SS:
dh.dh(DhResult, state.ssk, state.rs)
symmetricState.mixKey(state.symmetricState, DhResult)
sodium_memzero(DhResult)
break
default:
throw new Error('Invalid message pattern')
}
}
symmetricState.encryptAndHash(state.symmetricState, messageBuffer.subarray(moffset), payload)
moffset += symmetricState.encryptAndHash.bytesWritten
writeMessage.bytes = moffset
if (state.messagePatterns.length === 0) {
const tx = sodium_malloc(cipherState.STATELEN)
const rx = sodium_malloc(cipherState.STATELEN)
symmetricState.split(state.symmetricState, tx, rx, dh.DHLEN, dh.PKLEN)
return { tx, rx }
}
}
writeMessage.bytes = 0
function readMessage (state, message, payloadBuffer) {
assert(state instanceof HandshakeState)
assert(message.byteLength != null)
assert(payloadBuffer.byteLength != null)
const mpat = state.messagePatterns.shift()
let moffset = 0
assert(mpat != null)
assert(mpat.shift() !== state.role)
for (const token of mpat) {
switch (token) {
case TOK_E:
assert(state.re == null)
assert(message.byteLength - moffset >= dh.PKLEN)
// PKLEN instead of DHLEN since they are different in out case
state.re = sodium_malloc(dh.PKLEN)
state.re.set(message.subarray(moffset, moffset + dh.PKLEN))
moffset += dh.PKLEN
symmetricState.mixHash(state.symmetricState, state.re)
break
case TOK_S: {
assert(state.rs == null)
state.rs = sodium_malloc(dh.PKLEN)
let bytes = 0
if (symmetricState._hasKey(state.symmetricState)) {
bytes = dh.PKLEN + 16
} else {
bytes = dh.PKLEN
}
assert(message.byteLength - moffset >= bytes)
symmetricState.decryptAndHash(
state.symmetricState,
state.rs,
message.subarray(moffset, moffset + bytes) // <- called temp in noise spec
)
moffset += symmetricState.decryptAndHash.bytesRead
break
}
case TOK_EE:
dh.dh(DhResult, state.esk, state.re)
symmetricState.mixKey(state.symmetricState, DhResult)
sodium_memzero(DhResult)
break
case TOK_ES:
if (state.role === INITIATOR) dh.dh(DhResult, state.esk, state.rs)
else dh.dh(DhResult, state.ssk, state.re)
symmetricState.mixKey(state.symmetricState, DhResult)
sodium_memzero(DhResult)
break
case TOK_SE:
if (state.role === INITIATOR) dh.dh(DhResult, state.ssk, state.re)
else dh.dh(DhResult, state.esk, state.rs)
symmetricState.mixKey(state.symmetricState, DhResult)
sodium_memzero(DhResult)
break
case TOK_SS:
dh.dh(DhResult, state.ssk, state.rs)
symmetricState.mixKey(state.symmetricState, DhResult)
sodium_memzero(DhResult)
break
default:
throw new Error('Invalid message pattern')
}
}
symmetricState.decryptAndHash(state.symmetricState, payloadBuffer, message.subarray(moffset))
// How many bytes were written to payload (minus the TAG/MAC)
readMessage.bytes = symmetricState.decryptAndHash.bytesWritten
if (state.messagePatterns.length === 0) {
const tx = sodium_malloc(cipherState.STATELEN)
const rx = sodium_malloc(cipherState.STATELEN)
symmetricState.split(state.symmetricState, rx, tx, dh.DHLEN, dh.PKLEN)
return { tx, rx }
}
}
readMessage.bytes = 0
function keygen (obj, sk) {
if (!obj) {
obj = { publicKey: sodium_malloc(dh.PKLEN), secretKey: sodium_malloc(dh.SKLEN) }
return keygen(obj)
}
if (obj.publicKey) {
dh.generateKeypair(obj.publicKey, obj.secretKey)
return obj
}
if (obj.byteLength != null) dh.generateKeypair(null, obj)
}
function seedKeygen (seed) {
const obj = { publicKey: sodium_malloc(dh.PKLEN), secretKey: sodium_malloc(dh.SKLEN) }
dh.generateSeedKeypair(obj.publicKey, obj.secretKey, seed)
return obj
}
return Object.freeze({
initialize,
writeMessage,
readMessage,
destroy,
keygen,
seedKeygen,
createHandshake,
SKLEN: dh.SKLEN,
PKLEN: dh.PKLEN
})
}

@@ -53,3 +328,3 @@

// responder, <-
var PATTERNS = Object.freeze({
const PATTERNS = Object.freeze({
N: {

@@ -183,3 +458,3 @@ premessages: [

function sodiumBufferCopy (src) {
var buf = sodium_malloc(src.byteLength)
const buf = sodium_malloc(src.byteLength)
buf.set(src)

@@ -189,258 +464,2 @@ return buf

function initialize (handshakePattern, initiator, prologue, s, e, rs, re) {
assert(Object.keys(PATTERNS).includes(handshakePattern), 'Unsupported handshake pattern')
assert(typeof initiator === 'boolean', 'Initiator must be a boolean')
assert(prologue.byteLength != null, 'prolouge must be a Buffer')
assert(e == null ? true : e.publicKey.byteLength === dh.PKLEN, `e.publicKey must be ${dh.PKLEN} bytes`)
assert(e == null ? true : e.secretKey.byteLength === dh.SKLEN, `e.secretKey must be ${dh.SKLEN} bytes`)
assert(rs == null ? true : rs.byteLength === dh.PKLEN, `rs must be ${dh.PKLEN} bytes`)
assert(re == null ? true : re.byteLength === dh.PKLEN, `re must be ${dh.PKLEN} bytes`)
var state = new HandshakeState()
var protocolName = Uint8Array.from(`Noise_${handshakePattern}_25519_ChaChaPoly_BLAKE2b`, toCharCode)
symmetricState.initializeSymmetric(state.symmetricState, protocolName)
symmetricState.mixHash(state.symmetricState, prologue)
state.role = initiator === true ? INITIATOR : RESPONDER
if (s != null) {
assert(s.publicKey.byteLength === dh.PKLEN, `s.publicKey must be ${dh.PKLEN} bytes`)
assert(s.secretKey.byteLength === dh.SKLEN, `s.secretKey must be ${dh.SKLEN} bytes`)
state.spk = sodiumBufferCopy(s.publicKey)
state.ssk = sodiumBufferCopy(s.secretKey)
}
if (e != null) {
assert(e.publicKey.byteLength === dh.PKLEN)
assert(e.secretKey.byteLength === dh.SKLEN)
state.epk = sodiumBufferCopy(e.publicKey)
state.esk = sodiumBufferCopy(e.secretKey)
}
if (rs != null) {
assert(rs.byteLength === dh.PKLEN)
state.rs = sodiumBufferCopy(rs)
}
if (re != null) {
assert(re.byteLength === dh.PKLEN)
state.re = sodiumBufferCopy(re)
}
// hashing
var pat = PATTERNS[handshakePattern]
for (var pattern of clone(pat.premessages)) {
var patternRole = pattern.shift()
for (var token of pattern) {
switch (token) {
case TOK_E:
assert(state.role === patternRole ? state.epk.byteLength != null : state.re.byteLength != null)
symmetricState.mixHash(state.symmetricState, state.role === patternRole ? state.epk : state.re)
break
case TOK_S:
assert(state.role === patternRole ? state.spk.byteLength != null : state.rs.byteLength != null)
symmetricState.mixHash(state.symmetricState, state.role === patternRole ? state.spk : state.rs)
break
default:
throw new Error('Invalid premessage pattern')
}
}
}
state.messagePatterns = clone(pat.messagePatterns)
assert(state.messagePatterns.filter(p => p[0] === INITIATOR).some(p => p.includes(TOK_S))
? (state.spk !== null && state.ssk !== null)
: true, // Default if none is found
'This handshake pattern requires a static keypair')
return state
}
var DhResult = sodium_malloc(dh.DHLEN)
function writeMessage (state, payload, messageBuffer) {
assert(state instanceof HandshakeState)
assert(payload.byteLength != null)
assert(messageBuffer.byteLength != null)
var mpat = state.messagePatterns.shift()
var moffset = 0
assert(mpat != null)
assert(state.role === mpat.shift())
for (var token of mpat) {
switch (token) {
case TOK_E:
assert(state.epk == null)
assert(state.esk == null)
state.epk = sodium_malloc(dh.PKLEN)
state.esk = sodium_malloc(dh.SKLEN)
dh.generateKeypair(state.epk, state.esk)
messageBuffer.set(state.epk, moffset)
moffset += state.epk.byteLength
symmetricState.mixHash(state.symmetricState, state.epk)
break
case TOK_S:
assert(state.spk.byteLength === dh.PKLEN)
symmetricState.encryptAndHash(state.symmetricState, messageBuffer.subarray(moffset), state.spk)
moffset += symmetricState.encryptAndHash.bytesWritten
break
case TOK_EE:
dh.dh(DhResult, state.esk, state.re)
symmetricState.mixKey(state.symmetricState, DhResult)
sodium_memzero(DhResult)
break
case TOK_ES:
if (state.role === INITIATOR) dh.dh(DhResult, state.esk, state.rs)
else dh.dh(DhResult, state.ssk, state.re)
symmetricState.mixKey(state.symmetricState, DhResult)
sodium_memzero(DhResult)
break
case TOK_SE:
if (state.role === INITIATOR) dh.dh(DhResult, state.ssk, state.re)
else dh.dh(DhResult, state.esk, state.rs)
symmetricState.mixKey(state.symmetricState, DhResult)
sodium_memzero(DhResult)
break
case TOK_SS:
dh.dh(DhResult, state.ssk, state.rs)
symmetricState.mixKey(state.symmetricState, DhResult)
sodium_memzero(DhResult)
break
default:
throw new Error('Invalid message pattern')
}
}
symmetricState.encryptAndHash(state.symmetricState, messageBuffer.subarray(moffset), payload)
moffset += symmetricState.encryptAndHash.bytesWritten
writeMessage.bytes = moffset
if (state.messagePatterns.length === 0) {
var tx = sodium_malloc(cipherState.STATELEN)
var rx = sodium_malloc(cipherState.STATELEN)
symmetricState.split(state.symmetricState, tx, rx)
return { tx, rx }
}
}
writeMessage.bytes = 0
function readMessage (state, message, payloadBuffer) {
assert(state instanceof HandshakeState)
assert(message.byteLength != null)
assert(payloadBuffer.byteLength != null)
var mpat = state.messagePatterns.shift()
var moffset = 0
assert(mpat != null)
assert(mpat.shift() !== state.role)
for (var token of mpat) {
switch (token) {
case TOK_E:
assert(state.re == null)
assert(message.byteLength - moffset >= dh.PKLEN)
// PKLEN instead of DHLEN since they are different in out case
state.re = sodium_malloc(dh.PKLEN)
state.re.set(message.subarray(moffset, moffset + dh.PKLEN))
moffset += dh.PKLEN
symmetricState.mixHash(state.symmetricState, state.re)
break
case TOK_S:
assert(state.rs == null)
state.rs = sodium_malloc(dh.PKLEN)
var bytes = 0
if (symmetricState._hasKey(state.symmetricState)) {
bytes = dh.PKLEN + 16
} else {
bytes = dh.PKLEN
}
assert(message.byteLength - moffset >= bytes)
symmetricState.decryptAndHash(
state.symmetricState,
state.rs,
message.subarray(moffset, moffset + bytes) // <- called temp in noise spec
)
moffset += symmetricState.decryptAndHash.bytesRead
break
case TOK_EE:
dh.dh(DhResult, state.esk, state.re)
symmetricState.mixKey(state.symmetricState, DhResult)
sodium_memzero(DhResult)
break
case TOK_ES:
if (state.role === INITIATOR) dh.dh(DhResult, state.esk, state.rs)
else dh.dh(DhResult, state.ssk, state.re)
symmetricState.mixKey(state.symmetricState, DhResult)
sodium_memzero(DhResult)
break
case TOK_SE:
if (state.role === INITIATOR) dh.dh(DhResult, state.ssk, state.re)
else dh.dh(DhResult, state.esk, state.rs)
symmetricState.mixKey(state.symmetricState, DhResult)
sodium_memzero(DhResult)
break
case TOK_SS:
dh.dh(DhResult, state.ssk, state.rs)
symmetricState.mixKey(state.symmetricState, DhResult)
sodium_memzero(DhResult)
break
default:
throw new Error('Invalid message pattern')
}
}
symmetricState.decryptAndHash(state.symmetricState, payloadBuffer, message.subarray(moffset))
// How many bytes were written to payload (minus the TAG/MAC)
readMessage.bytes = symmetricState.decryptAndHash.bytesWritten
if (state.messagePatterns.length === 0) {
var tx = sodium_malloc(cipherState.STATELEN)
var rx = sodium_malloc(cipherState.STATELEN)
symmetricState.split(state.symmetricState, rx, tx)
return { tx, rx }
}
}
readMessage.bytes = 0
function destroy (state) {

@@ -487,24 +506,6 @@ if (state.symmetricState != null) {

function keygen (obj, sk) {
if (!obj) {
obj = { publicKey: sodium_malloc(PKLEN), secretKey: sodium_malloc(SKLEN) }
return keygen(obj)
}
if (obj.publicKey) {
dh.generateKeypair(obj.publicKey, obj.secretKey)
return obj
}
if (obj.byteLength != null) dh.generateKeypair(null, obj)
}
function seedKeygen (seed) {
var obj = { publicKey: sodium_malloc(PKLEN), secretKey: sodium_malloc(SKLEN) }
dh.generateSeedKeypair(obj.publicKey, obj.secretKey, seed)
return obj
}
function toCharCode (s) {
return s.charCodeAt(0)
}
module.exports = createHandshake

@@ -7,6 +7,6 @@ /* eslint-disable camelcase */

const hmacBlake2b = require('hmac-blake2b')
const dh = require('./dh')
const HASHLEN = 64
const BLOCKLEN = 128
const ALG = 'BLAKE2b'

@@ -16,7 +16,34 @@ assert(hmacBlake2b.KEYBYTES === BLOCKLEN, 'mismatching hmac BLOCKLEN')

module.exports = {
HASHLEN,
BLOCKLEN,
hash,
hkdf
const TempKey = sodium_malloc(HASHLEN)
const Byte0x01 = new Uint8Array([0x01])
const Byte0x02 = new Uint8Array([0x02])
const Byte0x03 = new Uint8Array([0x03])
module.exports = ({ dh }) => {
return {
HASHLEN,
BLOCKLEN,
ALG,
hash,
hkdf
}
function hkdf (out1, out2, out3, chainingKey, inputKeyMaterial) {
assert(out1.byteLength === HASHLEN)
assert(out2.byteLength === HASHLEN)
assert(out3 == null ? true : out3.byteLength === HASHLEN)
assert(chainingKey.byteLength === HASHLEN)
assert([0, 32, dh.DHLEN, dh.PKLEN].includes(inputKeyMaterial.byteLength))
sodium_memzero(TempKey)
hmac(TempKey, chainingKey, [inputKeyMaterial])
hmac(out1, TempKey, [Byte0x01])
hmac(out2, TempKey, [out1, Byte0x02])
if (out3 != null) {
hmac(out3, TempKey, [out2, Byte0x03])
}
sodium_memzero(TempKey)
}
}

@@ -34,25 +61,1 @@

}
const TempKey = sodium_malloc(HASHLEN)
const Byte0x01 = new Uint8Array([0x01])
const Byte0x02 = new Uint8Array([0x02])
const Byte0x03 = new Uint8Array([0x03])
function hkdf (out1, out2, out3, chainingKey, inputKeyMaterial) {
assert(out1.byteLength === HASHLEN)
assert(out2.byteLength === HASHLEN)
assert(out3 == null ? true : out3.byteLength === HASHLEN)
assert(chainingKey.byteLength === HASHLEN)
assert([0, 32, dh.DHLEN, dh.PKLEN].includes(inputKeyMaterial.byteLength))
sodium_memzero(TempKey)
hmac(TempKey, chainingKey, [inputKeyMaterial])
hmac(out1, TempKey, [Byte0x01])
hmac(out2, TempKey, [out1, Byte0x02])
if (out3 != null) {
hmac(out3, TempKey, [out2, Byte0x03])
}
sodium_memzero(TempKey)
}

@@ -1,1 +0,13 @@

module.exports = require('./handshake-state')
const dh = require('./dh')()
const hash = require('./hash')({ dh })
const cipher = require('./cipher')()
const cipherState = require('./cipher-state')({ cipher })
const symmetricState = require('./symmetric-state')({ hash, cipherState })
module.exports = require('./handshake-state')({
dh,
hash,
cipher,
cipherState,
symmetricState
})
{
"name": "noise-protocol",
"version": "3.0.1",
"version": "3.0.2",
"description": "Javascript implementation of the Noise Protocol Framework based on libsodium",

@@ -8,12 +8,12 @@ "main": "index.js",

"clone": "^2.1.2",
"hmac-blake2b": "^2.0.0",
"hmac-blake2b": "^2.0.2",
"nanoassert": "^2.0.0",
"sodium-universal": "^3.0.2"
"sodium-universal": "^4.0.0"
},
"devDependencies": {
"browserify": "^16.5.1",
"c8": "^7.1.2",
"standard": "^14.3.4",
"tape": "^5.0.0",
"tape-run": "^7.0.0"
"browserify": "^17.0.0",
"c8": "^7.12.0",
"standard": "^17.0.0",
"tape": "^5.6.1",
"tape-run": "^10.0.0"
},

@@ -20,0 +20,0 @@ "scripts": {

# `noise-protocol`
[![Build Status](https://travis-ci.org/emilbayes/noise-protocol.svg?branch=master)](https://travis-ci.org/emilbayes/noise-protocol)
[![Build Status](https://github.com/emilbayes/noise-protocol/actions/workflows/npm.yml/badge.svg?branch=master)](https://github.com/emilbayes/noise-protocol/actions/workflows/npm.yml)

@@ -188,2 +188,12 @@ > Javascript implementation of the Noise Protocol Framework based on libsodium

### Custom algorithms
You can customise the handshake state by calling `noise.createHandshake(algs)`
with `algs = { dh, hash, cipher, cipherState, symmetricState }`. Please refer
to the respective implementations in the source to see how to swap pieces.
Please note that this is dangerous, unless you've read the noise specification
very carefully and know what you are doing. `createHandshake` will then return
a new `initialize` function from which you can create start handshakes with
your custom algorithms.
## Install

@@ -190,0 +200,0 @@

/* eslint-disable camelcase */
const { sodium_malloc, sodium_memzero } = require('sodium-universal/memory')
var assert = require('nanoassert')
var cipherState = require('./cipher-state')
var hash = require('./hash')
const assert = require('nanoassert')
var STATELEN = hash.HASHLEN + hash.HASHLEN + cipherState.STATELEN
var HASHLEN = hash.HASHLEN
module.exports = ({ hash, cipherState }) => {
const STATELEN = hash.HASHLEN + hash.HASHLEN + cipherState.STATELEN
const HASHLEN = hash.HASHLEN
module.exports = {
STATELEN,
initializeSymmetric,
mixKey,
mixHash,
mixKeyAndHash,
getHandshakeHash,
encryptAndHash,
decryptAndHash,
split,
_hasKey
}
const CHAINING_KEY_BEGIN = 0
const CHAINING_KEY_END = hash.HASHLEN
const HASH_BEGIN = CHAINING_KEY_END
const HASH_END = HASH_BEGIN + hash.HASHLEN
const CIPHER_BEGIN = HASH_END
const CIPHER_END = CIPHER_BEGIN + cipherState.STATELEN
var CHAINING_KEY_BEGIN = 0
var CHAINING_KEY_END = hash.HASHLEN
var HASH_BEGIN = CHAINING_KEY_END
var HASH_END = HASH_BEGIN + hash.HASHLEN
var CIPHER_BEGIN = HASH_END
var CIPHER_END = CIPHER_BEGIN + cipherState.STATELEN
function initializeSymmetric (state, protocolName) {
assert(state.byteLength === STATELEN)
assert(protocolName.byteLength != null)
function initializeSymmetric (state, protocolName) {
assert(state.byteLength === STATELEN)
assert(protocolName.byteLength != null)
sodium_memzero(state)
if (protocolName.byteLength <= HASHLEN) state.set(protocolName, HASH_BEGIN)
else hash.hash(state.subarray(HASH_BEGIN, HASH_END), [protocolName])
sodium_memzero(state)
if (protocolName.byteLength <= HASHLEN) state.set(protocolName, HASH_BEGIN)
else hash.hash(state.subarray(HASH_BEGIN, HASH_END), [protocolName])
state.subarray(CHAINING_KEY_BEGIN, CHAINING_KEY_END).set(state.subarray(HASH_BEGIN, HASH_END))
state.subarray(CHAINING_KEY_BEGIN, CHAINING_KEY_END).set(state.subarray(HASH_BEGIN, HASH_END))
cipherState.initializeKey(state.subarray(CIPHER_BEGIN, CIPHER_END), null)
}
cipherState.initializeKey(state.subarray(CIPHER_BEGIN, CIPHER_END), null)
}
const TempKey = sodium_malloc(HASHLEN)
function mixKey (state, inputKeyMaterial, dhlen, pklen) {
assert(state.byteLength === STATELEN)
assert(inputKeyMaterial.byteLength != null)
var TempKey = sodium_malloc(HASHLEN)
function mixKey (state, inputKeyMaterial) {
assert(state.byteLength === STATELEN)
assert(inputKeyMaterial.byteLength != null)
hash.hkdf(
state.subarray(CHAINING_KEY_BEGIN, CHAINING_KEY_END),
TempKey,
null,
state.subarray(CHAINING_KEY_BEGIN, CHAINING_KEY_END),
inputKeyMaterial,
dhlen,
pklen
)
hash.hkdf(
state.subarray(CHAINING_KEY_BEGIN, CHAINING_KEY_END),
TempKey,
null,
state.subarray(CHAINING_KEY_BEGIN, CHAINING_KEY_END),
inputKeyMaterial
)
// HASHLEN is always 64 here, so we truncate to 32 bytes per the spec
cipherState.initializeKey(state.subarray(CIPHER_BEGIN, CIPHER_END), TempKey.subarray(0, 32))
sodium_memzero(TempKey)
}
// HASHLEN is always 64 here, so we truncate to 32 bytes per the spec
cipherState.initializeKey(state.subarray(CIPHER_BEGIN, CIPHER_END), TempKey.subarray(0, 32))
sodium_memzero(TempKey)
}
function mixHash (state, data) {
assert(state.byteLength === STATELEN)
function mixHash (state, data) {
assert(state.byteLength === STATELEN)
const h = state.subarray(HASH_BEGIN, HASH_END)
var h = state.subarray(HASH_BEGIN, HASH_END)
hash.hash(h, [h, data])
}
hash.hash(h, [h, data])
}
const TempHash = sodium_malloc(HASHLEN)
function mixKeyAndHash (state, inputKeyMaterial, dhlen, pklen) {
assert(state.byteLength === STATELEN)
assert(inputKeyMaterial.byteLength != null)
var TempHash = sodium_malloc(HASHLEN)
function mixKeyAndHash (state, inputKeyMaterial) {
assert(state.byteLength === STATELEN)
assert(inputKeyMaterial.byteLength != null)
hash.hkdf(
state.subarray(CHAINING_KEY_BEGIN, CHAINING_KEY_END),
TempHash,
TempKey,
state.subarray(CHAINING_KEY_BEGIN, CHAINING_KEY_END),
inputKeyMaterial,
dhlen,
pklen
)
hash.hkdf(
state.subarray(CHAINING_KEY_BEGIN, CHAINING_KEY_END),
TempHash,
TempKey,
state.subarray(CHAINING_KEY_BEGIN, CHAINING_KEY_END),
inputKeyMaterial
)
mixHash(state, TempHash)
sodium_memzero(TempHash)
mixHash(state, TempHash)
sodium_memzero(TempHash)
// HASHLEN is always 64 here, so we truncate to 32 bytes per the spec
cipherState.initializeKey(state.subarray(CIPHER_BEGIN, CIPHER_END), TempKey.subarray(0, 32))
sodium_memzero(TempKey)
}
// HASHLEN is always 64 here, so we truncate to 32 bytes per the spec
cipherState.initializeKey(state.subarray(CIPHER_BEGIN, CIPHER_END), TempKey.subarray(0, 32))
sodium_memzero(TempKey)
}
function getHandshakeHash (state, out) {
assert(state.byteLength === STATELEN)
assert(out.byteLength === HASHLEN)
function getHandshakeHash (state, out) {
assert(state.byteLength === STATELEN)
assert(out.byteLength === HASHLEN)
out.set(state.subarray(HASH_BEGIN, HASH_END))
}
out.set(state.subarray(HASH_BEGIN, HASH_END))
}
// ciphertext is the output here
function encryptAndHash (state, ciphertext, plaintext) {
assert(state.byteLength === STATELEN)
assert(ciphertext.byteLength != null)
assert(plaintext.byteLength != null)
// ciphertext is the output here
function encryptAndHash (state, ciphertext, plaintext) {
assert(state.byteLength === STATELEN)
assert(ciphertext.byteLength != null)
assert(plaintext.byteLength != null)
const cstate = state.subarray(CIPHER_BEGIN, CIPHER_END)
const h = state.subarray(HASH_BEGIN, HASH_END)
var cstate = state.subarray(CIPHER_BEGIN, CIPHER_END)
var h = state.subarray(HASH_BEGIN, HASH_END)
cipherState.encryptWithAd(cstate, ciphertext, h, plaintext)
encryptAndHash.bytesRead = cipherState.encryptWithAd.bytesRead
encryptAndHash.bytesWritten = cipherState.encryptWithAd.bytesWritten
mixHash(state, ciphertext.subarray(0, encryptAndHash.bytesWritten))
}
encryptAndHash.bytesRead = 0
encryptAndHash.bytesWritten = 0
cipherState.encryptWithAd(cstate, ciphertext, h, plaintext)
encryptAndHash.bytesRead = cipherState.encryptWithAd.bytesRead
encryptAndHash.bytesWritten = cipherState.encryptWithAd.bytesWritten
mixHash(state, ciphertext.subarray(0, encryptAndHash.bytesWritten))
}
encryptAndHash.bytesRead = 0
encryptAndHash.bytesWritten = 0
// plaintext is the output here
function decryptAndHash (state, plaintext, ciphertext) {
assert(state.byteLength === STATELEN)
assert(plaintext.byteLength != null)
assert(ciphertext.byteLength != null)
// plaintext is the output here
function decryptAndHash (state, plaintext, ciphertext) {
assert(state.byteLength === STATELEN)
assert(plaintext.byteLength != null)
assert(ciphertext.byteLength != null)
const cstate = state.subarray(CIPHER_BEGIN, CIPHER_END)
const h = state.subarray(HASH_BEGIN, HASH_END)
var cstate = state.subarray(CIPHER_BEGIN, CIPHER_END)
var h = state.subarray(HASH_BEGIN, HASH_END)
cipherState.decryptWithAd(cstate, plaintext, h, ciphertext)
decryptAndHash.bytesRead = cipherState.decryptWithAd.bytesRead
decryptAndHash.bytesWritten = cipherState.decryptWithAd.bytesWritten
mixHash(state, ciphertext.subarray(0, decryptAndHash.bytesRead))
}
decryptAndHash.bytesRead = 0
decryptAndHash.bytesWritten = 0
cipherState.decryptWithAd(cstate, plaintext, h, ciphertext)
decryptAndHash.bytesRead = cipherState.decryptWithAd.bytesRead
decryptAndHash.bytesWritten = cipherState.decryptWithAd.bytesWritten
mixHash(state, ciphertext.subarray(0, decryptAndHash.bytesRead))
}
decryptAndHash.bytesRead = 0
decryptAndHash.bytesWritten = 0
const TempKey1 = sodium_malloc(HASHLEN)
const TempKey2 = sodium_malloc(HASHLEN)
const zerolen = new Uint8Array(0)
function split (state, cipherstate1, cipherstate2, dhlen, pklen) {
assert(state.byteLength === STATELEN)
assert(cipherstate1.byteLength === cipherState.STATELEN)
assert(cipherstate2.byteLength === cipherState.STATELEN)
var TempKey1 = sodium_malloc(HASHLEN)
var TempKey2 = sodium_malloc(HASHLEN)
var zerolen = new Uint8Array(0)
function split (state, cipherstate1, cipherstate2) {
assert(state.byteLength === STATELEN)
assert(cipherstate1.byteLength === cipherState.STATELEN)
assert(cipherstate2.byteLength === cipherState.STATELEN)
hash.hkdf(
TempKey1,
TempKey2,
null,
state.subarray(CHAINING_KEY_BEGIN, CHAINING_KEY_END),
zerolen,
dhlen,
pklen
)
hash.hkdf(
TempKey1,
TempKey2,
null,
state.subarray(CHAINING_KEY_BEGIN, CHAINING_KEY_END),
zerolen
)
// HASHLEN is always 64 here, so we truncate to 32 bytes per the spec
cipherState.initializeKey(cipherstate1, TempKey1.subarray(0, 32))
cipherState.initializeKey(cipherstate2, TempKey2.subarray(0, 32))
sodium_memzero(TempKey1)
sodium_memzero(TempKey2)
}
// HASHLEN is always 64 here, so we truncate to 32 bytes per the spec
cipherState.initializeKey(cipherstate1, TempKey1.subarray(0, 32))
cipherState.initializeKey(cipherstate2, TempKey2.subarray(0, 32))
sodium_memzero(TempKey1)
sodium_memzero(TempKey2)
}
function _hasKey (state) {
return cipherState.hasKey(state.subarray(CIPHER_BEGIN, CIPHER_END))
}
function _hasKey (state) {
return cipherState.hasKey(state.subarray(CIPHER_BEGIN, CIPHER_END))
return {
STATELEN,
initializeSymmetric,
mixKey,
mixHash,
mixKeyAndHash,
getHandshakeHash,
encryptAndHash,
decryptAndHash,
split,
_hasKey
}
}

@@ -8,4 +8,4 @@ /* eslint-disable camelcase */

const { randombytes_buf } = require('sodium-universal/randombytes')
var cipher = require('../cipher')
var test = require('tape')
const cipher = require('../cipher')()
const test = require('tape')

@@ -25,15 +25,15 @@ test('constants', function (assert) {

test('identity', function (assert) {
var key = Buffer.alloc(cipher.KEYLEN)
var nonce = Buffer.alloc(cipher.NONCELEN)
const key = Buffer.alloc(cipher.KEYLEN)
const nonce = Buffer.alloc(cipher.NONCELEN)
randombytes_buf(key)
randombytes_buf(nonce)
var key2 = Buffer.alloc(cipher.KEYLEN)
var nonce2 = Buffer.alloc(cipher.NONCELEN)
const key2 = Buffer.alloc(cipher.KEYLEN)
const nonce2 = Buffer.alloc(cipher.NONCELEN)
randombytes_buf(key2)
randombytes_buf(nonce2)
var plaintext = Buffer.from('Hello world')
var ciphertext = Buffer.alloc(plaintext.byteLength + cipher.MACLEN)
var decrypted = Buffer.alloc(plaintext.byteLength)
const plaintext = Buffer.from('Hello world')
const ciphertext = Buffer.alloc(plaintext.byteLength + cipher.MACLEN)
const decrypted = Buffer.alloc(plaintext.byteLength)

@@ -46,3 +46,3 @@ cipher.encrypt(ciphertext, key, nonce, null, plaintext)

for (var i = 0; i < ciphertext.length; i++) {
for (let i = 0; i < ciphertext.length; i++) {
ciphertext[i] ^= i + 1

@@ -60,17 +60,17 @@ assert.throws(_ => cipher.decrypt(decrypted, key, nonce, null, ciphertext))

test('identity with ad', function (assert) {
var key = Buffer.alloc(cipher.KEYLEN)
var nonce = Buffer.alloc(cipher.NONCELEN)
const key = Buffer.alloc(cipher.KEYLEN)
const nonce = Buffer.alloc(cipher.NONCELEN)
randombytes_buf(key)
randombytes_buf(nonce)
var ad = Buffer.from('version 0')
const ad = Buffer.from('version 0')
var key2 = Buffer.alloc(cipher.KEYLEN)
var nonce2 = Buffer.alloc(cipher.NONCELEN)
const key2 = Buffer.alloc(cipher.KEYLEN)
const nonce2 = Buffer.alloc(cipher.NONCELEN)
randombytes_buf(key2)
randombytes_buf(nonce2)
var plaintext = Buffer.from('Hello world')
var ciphertext = Buffer.alloc(plaintext.byteLength + cipher.MACLEN)
var decrypted = Buffer.alloc(plaintext.byteLength)
const plaintext = Buffer.from('Hello world')
const ciphertext = Buffer.alloc(plaintext.byteLength + cipher.MACLEN)
const decrypted = Buffer.alloc(plaintext.byteLength)

@@ -83,3 +83,3 @@ cipher.encrypt(ciphertext, key, nonce, ad, plaintext)

for (var i = 0; i < ciphertext.length; i++) {
for (let i = 0; i < ciphertext.length; i++) {
ciphertext[i] ^= 255

@@ -97,14 +97,14 @@ assert.throws(_ => cipher.decrypt(decrypted, key, nonce, ad, ciphertext))

test('rekey', function (assert) {
var key = Buffer.alloc(cipher.KEYLEN)
var nonce = Buffer.alloc(cipher.NONCELEN)
const key = Buffer.alloc(cipher.KEYLEN)
const nonce = Buffer.alloc(cipher.NONCELEN)
randombytes_buf(key)
randombytes_buf(nonce)
var keyCopy = Buffer.from(key)
const keyCopy = Buffer.from(key)
cipher.rekey(key, key)
assert.notOk(key.equals(keyCopy))
var plaintext = Buffer.from('Hello world')
var ciphertext = Buffer.alloc(plaintext.byteLength + cipher.MACLEN)
var decrypted = Buffer.alloc(plaintext.byteLength)
const plaintext = Buffer.from('Hello world')
const ciphertext = Buffer.alloc(plaintext.byteLength + cipher.MACLEN)
const decrypted = Buffer.alloc(plaintext.byteLength)

@@ -111,0 +111,0 @@ cipher.encrypt(ciphertext, key, nonce, null, plaintext)

@@ -1,3 +0,3 @@

var dh = require('../dh')
var test = require('tape')
const dh = require('../dh')()
const test = require('tape')

@@ -10,5 +10,5 @@ test('constants', function (assert) {

test('generateKeypair', function (assert) {
var kp1 = { sk: Buffer.alloc(dh.SKLEN), pk: Buffer.alloc(dh.PKLEN) }
var kp2 = { sk: Buffer.alloc(dh.SKLEN), pk: Buffer.alloc(dh.PKLEN) }
var kp3 = { sk: Buffer.alloc(dh.SKLEN), pk: Buffer.alloc(dh.PKLEN) }
const kp1 = { sk: Buffer.alloc(dh.SKLEN), pk: Buffer.alloc(dh.PKLEN) }
const kp2 = { sk: Buffer.alloc(dh.SKLEN), pk: Buffer.alloc(dh.PKLEN) }
const kp3 = { sk: Buffer.alloc(dh.SKLEN), pk: Buffer.alloc(dh.PKLEN) }

@@ -33,4 +33,4 @@ dh.generateKeypair(kp2.pk, kp2.sk)

test('initiator / responder', function (assert) {
var server = { sk: Buffer.alloc(dh.SKLEN), pk: Buffer.alloc(dh.PKLEN) }
var client = { sk: Buffer.alloc(dh.SKLEN), pk: Buffer.alloc(dh.PKLEN) }
const server = { sk: Buffer.alloc(dh.SKLEN), pk: Buffer.alloc(dh.PKLEN) }
const client = { sk: Buffer.alloc(dh.SKLEN), pk: Buffer.alloc(dh.PKLEN) }

@@ -40,4 +40,4 @@ dh.generateKeypair(server.pk, server.sk)

var dhc = Buffer.alloc(dh.DHLEN)
var dhs = Buffer.alloc(dh.DHLEN)
const dhc = Buffer.alloc(dh.DHLEN)
const dhs = Buffer.alloc(dh.DHLEN)

@@ -76,7 +76,7 @@ dh.dh(dhc, client.sk, server.pk)

test('bad keys', function (assert) {
var keypair = { sk: Buffer.alloc(dh.SKLEN), pk: Buffer.alloc(dh.PKLEN) }
const keypair = { sk: Buffer.alloc(dh.SKLEN), pk: Buffer.alloc(dh.PKLEN) }
dh.generateKeypair(keypair.pk, keypair.sk)
var dho = Buffer.alloc(dh.DHLEN)
for (var i = 0; i < badKeys.length; i++) {
const dho = Buffer.alloc(dh.DHLEN)
for (let i = 0; i < badKeys.length; i++) {
assert.throws(() => dh.dh(dho, keypair.sk, badKeys[i]))

@@ -83,0 +83,0 @@ }

@@ -1,3 +0,3 @@

var noise = require('..')
var test = require('tape')
const noise = require('..')
const test = require('tape')

@@ -4,0 +4,0 @@ test('Static key pattern without static keypair', function (assert) {

@@ -1,3 +0,4 @@

var hash = require('../hash')
var test = require('tape')
const dh = require('../dh')()
const hash = require('../hash')({ dh })
const test = require('tape')

@@ -4,0 +5,0 @@ test('constants', function (assert) {

@@ -1,14 +0,14 @@

var noise = require('../..')
var test = require('tape')
const noise = require('../..')
const test = require('tape')
test('N pattern', function (assert) {
var serverKeys = noise.keygen()
const serverKeys = noise.keygen()
var client = noise.initialize('N', true, Buffer.alloc(0), null, null, serverKeys.publicKey)
var server = noise.initialize('N', false, Buffer.alloc(0), serverKeys)
const client = noise.initialize('N', true, Buffer.alloc(0), null, null, serverKeys.publicKey)
const server = noise.initialize('N', false, Buffer.alloc(0), serverKeys)
var clientTx = Buffer.alloc(512)
var serverRx = Buffer.alloc(512)
const clientTx = Buffer.alloc(512)
const serverRx = Buffer.alloc(512)
var splitClient = noise.writeMessage(client, Buffer.from('Hello world'), clientTx)
const splitClient = noise.writeMessage(client, Buffer.from('Hello world'), clientTx)
assert.ok(noise.writeMessage.bytes > 11)

@@ -18,3 +18,3 @@ assert.false(Buffer.from(clientTx).includes(Buffer.from('Hello world')))

assert.false(Buffer.from(clientTx).includes(Buffer.from(client.esk)))
var splitServer = noise.readMessage(server, clientTx.subarray(0, noise.writeMessage.bytes), serverRx)
const splitServer = noise.readMessage(server, clientTx.subarray(0, noise.writeMessage.bytes), serverRx)
assert.equal(noise.readMessage.bytes, 11)

@@ -21,0 +21,0 @@

@@ -1,13 +0,13 @@

var noise = require('../..')
var test = require('tape')
const noise = require('../..')
const test = require('tape')
test('NN pattern', function (assert) {
var client = noise.initialize('NN', true, Buffer.alloc(0))
var server = noise.initialize('NN', false, Buffer.alloc(0))
const client = noise.initialize('NN', true, Buffer.alloc(0))
const server = noise.initialize('NN', false, Buffer.alloc(0))
var clientTx = Buffer.alloc(512)
var serverRx = Buffer.alloc(512)
const clientTx = Buffer.alloc(512)
const serverRx = Buffer.alloc(512)
var serverTx = Buffer.alloc(512)
var clientRx = Buffer.alloc(512)
const serverTx = Buffer.alloc(512)
const clientRx = Buffer.alloc(512)

@@ -19,5 +19,5 @@ assert.false(noise.writeMessage(client, Buffer.alloc(0), clientTx))

var splitServer = noise.writeMessage(server, Buffer.alloc(0), serverTx)
const splitServer = noise.writeMessage(server, Buffer.alloc(0), serverTx)
assert.ok(noise.writeMessage.bytes > 0)
var splitClient = noise.readMessage(client, serverTx.subarray(0, noise.writeMessage.bytes), clientRx)
const splitClient = noise.readMessage(client, serverTx.subarray(0, noise.writeMessage.bytes), clientRx)
assert.equal(noise.readMessage.bytes, 0)

@@ -24,0 +24,0 @@

@@ -1,13 +0,13 @@

var noise = require('../..')
var test = require('tape')
const noise = require('../..')
const test = require('tape')
test('XX pattern', function (assert) {
var client = noise.initialize('XX', true, Buffer.alloc(0), noise.keygen())
var server = noise.initialize('XX', false, Buffer.alloc(0), noise.keygen())
const client = noise.initialize('XX', true, Buffer.alloc(0), noise.keygen())
const server = noise.initialize('XX', false, Buffer.alloc(0), noise.keygen())
var clientTx = Buffer.alloc(512)
var serverRx = Buffer.alloc(512)
const clientTx = Buffer.alloc(512)
const serverRx = Buffer.alloc(512)
var serverTx = Buffer.alloc(512)
var clientRx = Buffer.alloc(512)
const serverTx = Buffer.alloc(512)
const clientRx = Buffer.alloc(512)

@@ -27,5 +27,5 @@ // ->

// ->
var splitClient = noise.writeMessage(client, Buffer.alloc(0), clientTx)
const splitClient = noise.writeMessage(client, Buffer.alloc(0), clientTx)
assert.ok(noise.writeMessage.bytes > 0)
var splitServer = noise.readMessage(server, clientTx.subarray(0, noise.writeMessage.bytes), serverRx)
const splitServer = noise.readMessage(server, clientTx.subarray(0, noise.writeMessage.bytes), serverRx)
assert.equal(noise.readMessage.bytes, 0)

@@ -32,0 +32,0 @@

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc