xsalsa20-encoding
Advanced tools
Comparing version 0.2.0 to 1.0.0
111
index.js
@@ -6,2 +6,43 @@ const xsalsa20 = require('xsalsa20') | ||
/** | ||
* Converts a value to a buffer, if possible, otherwise | ||
* `null` is returned. | ||
* @private | ||
* @param {?(Mixed)} value | ||
* @return {?(Buffer)} | ||
*/ | ||
function toBuffer(value) { | ||
if (Buffer.isBuffer(value)) { | ||
return value | ||
} | ||
if ('string' === typeof value) { | ||
return Buffer.from(value) | ||
} | ||
if (Array.isArray(value)) { | ||
return Buffer.from(value) | ||
} | ||
if (value && 'object' === typeof value && 'Buffer' === value.type) { | ||
// istanbul ignore next | ||
if (Array.isArray(value.data)) { | ||
return Buffer.from(value.data) | ||
} | ||
} | ||
return null | ||
} | ||
/** | ||
* The size in bytes for the nonce used to encipher/decipher | ||
* values encoded or decoded by this module. | ||
* @public | ||
*/ | ||
const NONCE_BYTES = 24 | ||
/** | ||
* The default encoding for the `valueEncoding` option. | ||
* @private | ||
*/ | ||
class DefaultEncoding { | ||
@@ -12,2 +53,12 @@ encode(value) { return value } | ||
/** | ||
* Creates and returns an abstract-encoding interface to encode | ||
* and decode values using the Xsalsa20 cipher. Nonces are | ||
* prepended (attached) to encoded output and must be a present | ||
* when decoding. Detached nonces may be used if the `Buffer` instance | ||
* to decode as a `nonce` property set on it. | ||
* @param {Buffer} key | ||
* @param {?(Object)} opts | ||
* @return {Object} | ||
*/ | ||
function createCodec(key, opts) { | ||
@@ -55,9 +106,9 @@ if (!opts || 'object' !== typeof opts) { | ||
const ciphertext = buffer.slice(offset + 24) | ||
const ciphertext = buffer.slice(offset + NONCE_BYTES) | ||
const nonce = buffer.slice(offset) | ||
assert(ciphertext.length >= length - 24, | ||
assert(ciphertext.length >= length - NONCE_BYTES, | ||
'cannot store ciphertext in buffer at offset.') | ||
crypto.randomBytes(24).copy(nonce) | ||
crypto.randomBytes(NONCE_BYTES).copy(nonce) | ||
@@ -84,3 +135,12 @@ const xor = xsalsa20(nonce, key) | ||
const ciphertext = buffer.slice(start + 24, end) | ||
// istanbul ignore next | ||
const ciphertext = Buffer.isBuffer(buffer.nonce) | ||
? Object.assign(buffer.slice(start, end), { nonce: buffer.nonce }) | ||
: buffer.slice(start + NONCE_BYTES, end) | ||
// istanbul ignore next | ||
const nonce = Buffer.isBuffer(buffer.nonce) | ||
? buffer.nonce | ||
: buffer.slice(start, start + NONCE_BYTES) | ||
const length = encodingLength(ciphertext) | ||
@@ -92,6 +152,8 @@ | ||
const plaintext = Buffer.allocUnsafe(length - 24) | ||
const nonce = buffer.slice(start, start + 24) | ||
const xor = xsalsa20(nonce, key) | ||
const plaintext = buffer.nonce | ||
? Buffer.allocUnsafe(length) | ||
: Buffer.allocUnsafe(length - NONCE_BYTES) | ||
xor.update(ciphertext, plaintext) | ||
@@ -108,29 +170,20 @@ xor.finalize() | ||
/** | ||
* @param {} | ||
* @return {Number} | ||
*/ | ||
function encodingLength(value) { | ||
const buffer = toBuffer(value) | ||
return buffer && buffer.length ? 24 + buffer.length : 0 | ||
} | ||
function toBuffer(value) { | ||
if (Buffer.isBuffer(value)) { | ||
return value | ||
if (buffer && buffer.nonce) { | ||
return buffer.length | ||
} else { | ||
return buffer && buffer.length ? NONCE_BYTES + buffer.length : 0 | ||
} | ||
if ('string' === typeof value) { | ||
return Buffer.from(value) | ||
} | ||
if (Array.isArray(value)) { | ||
return Buffer.from(value) | ||
} | ||
if (value && 'object' === typeof value && 'Buffer' === value.type) { | ||
if (Array.isArray(value.data)) { | ||
return Buffer.from(value.data) | ||
} | ||
} | ||
return null | ||
} | ||
module.exports = createCodec | ||
/** | ||
* Module exports. | ||
*/ | ||
module.exports = Object.assign(createCodec, { | ||
NONCE_BYTES | ||
}) |
{ | ||
"name": "xsalsa20-encoding", | ||
"version": "0.2.0", | ||
"version": "1.0.0", | ||
"description": "XSalsa20 codec that implements tha abstract-encoding interface.", | ||
"main": "index.js", | ||
"scripts": { | ||
"test": "tape test.js" | ||
"test": "nyc tape test.js" | ||
}, | ||
@@ -18,2 +18,3 @@ "keywords": [ | ||
"devDependencies": { | ||
"nyc": "^15.0.0", | ||
"protocol-buffers": "^4.1.0", | ||
@@ -20,0 +21,0 @@ "tape": "^4.10.1" |
13
test.js
@@ -74,1 +74,14 @@ const blake2b = require('blake2b') | ||
}) | ||
test('codec.encode() | codec.decode() - detached', (t) => { | ||
const key = crypto.randomBytes(32) | ||
const codec = Codec(key) | ||
const plaintext = Buffer.from('hello') | ||
const encoded = codec.encode(plaintext) | ||
const nonce = encoded.slice(0, 24) | ||
const ciphertext = encoded.slice(24) | ||
ciphertext.nonce = nonce | ||
const decoded = codec.decode(ciphertext) | ||
t.ok(0 === Buffer.compare(plaintext, decoded)) | ||
t.end() | ||
}) |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
11521
7
234
1
3