Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

hypercore-xsalsa20-onwrite-hook

Package Overview
Dependencies
Maintainers
3
Versions
9
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

hypercore-xsalsa20-onwrite-hook - npm Package Compare versions

Comparing version 1.0.2 to 2.0.0

47

example.js
const replicate = require('hypercore-replicate')
const hypercore = require('hypercore')
const crypto = require('hypercore-crypto')
const File = require('hypercore-indexed-file')
const pump = require('pump')
const hook = require('./')

@@ -10,20 +12,39 @@ const ram = require('random-access-memory')

const { publicKey, secretKey } = crypto.keyPair()
const nonces = ram()
const feed = hypercore(ram, publicKey, {
const source = File(__filename, {
key: publicKey,
secretKey,
onwrite: hook(nonces, key)
})
}, (err) => {
const copy = hypercore(ram, publicKey, {
onwrite: hook(nonces, key)
})
const cipher = hypercore(ram, publicKey, {
secretKey,
onwrite: hook(key)
})
feed.append(Buffer.from('hello'), (err) => {
feed.head(console.log) // ciphertext
})
const edge = hypercore(ram, publicKey)
replicate(feed, copy, (err) => {
if (err) throw err
copy.head(console.log) // plaintext
const reader = hypercore(ram, publicKey, {
onwrite: hook(key)
})
source.ready(() => {
//source.head(console.log) // plaintext
// load cipher hypercore
pump(source.createReadStream(), cipher.createWriteStream(), (err) => {
if (err) throw err
cipher.head(console.log) // ciphertext
replicate(cipher, edge, (err) => {
if (err) throw err
edge.head(console.log) // ciphertext
replicate(edge, reader, (err) => {
if (err) throw err
reader.head(console.log) // plaintext
reader.createReadStream().pipe(process.stdout)
})
})
})
})
})
const xsalsa20 = require('xsalsa20-encoding')
const varint = require('varint')
const crypto = require('hypercore-crypto')
const assert = require('assert')

@@ -15,17 +17,9 @@

* Creates a `onwrite()` hook for a Hypercore feed that uses the
* xsalsa20 cipher to encipher or decipher blocks in a Hypercore feed. Blocks
* that are written to a Hypercore feed are encrypted detached from the
* nonce used for encryption. Nonces are written to a user supplied
* "nonce storage" which can be reused for deciphering blocks appended
* to a Hypercore feed.
*
* This function preserves block sizes but requires an external storage
* for nonces. Users should provide a `random-access-storage` compliant
* instance or a factory function that returns one.
* @param {Function<Object,Buffer>} createStorage
* xsalsa20 cipher to encipher or decipher blocks in a Hypercore feed.
* Nonces are computed from the Hypercore feed's public key and block index.
* @param {String|Buffer} key
* @param {?(Object)} opts
* @return {Function}
*/
function createHook(createStorage, key, opts) {
function createHook(key, opts) {
// istanbul ignore next
if ('string' === typeof key) {

@@ -35,35 +29,27 @@ key = Buffer.from(key, 'hex')

opts = Object.assign({}, opts)
assert(Buffer.isBuffer(key), '`key` is not a buffer.')
if (createStorage && 'object' !== typeof createStorage) {
assert('function' === typeof createStorage,
'`createStorage` is not a function.')
}
const storage = 'function' === typeof createStorage
? createStorage(opts, key)
: createStorage
return onwrite
function onwrite(index, data, peer, done) {
const offset = index * NONCE_BYTES
const block = Buffer.from(varint.encode(index))
const nonce = Buffer.allocUnsafe(24)
// nonce = hash(key || block)
crypto.data(Buffer.concat([this.key, block])).copy(nonce)
// if not replicating from a peer, encipher plaintext,
// otherwise decipher ciphertext with computed nonce
if (!peer) {
const encrypted = xsalsa20(key).encode(data)
const nonce = encrypted.slice(0, NONCE_BYTES)
encrypted.slice(NONCE_BYTES).copy(data)
storage.write(offset, nonce, done)
xsalsa20(key, { nonce: () => nonce })
.encode(data)
.slice(NONCE_BYTES)
.copy(data)
} else {
storage.read(offset, NONCE_BYTES, (err, nonce) => {
// istanbul ignore next
if (err) { return done(err) }
const attached = Buffer.concat([nonce, data])
const decrypted = xsalsa20(key).decode(attached)
decrypted.copy(data)
done(null)
})
xsalsa20(key)
.decode(Buffer.concat([nonce, data]))
.copy(data)
}
done(null)
}

@@ -75,4 +61,2 @@ }

*/
module.exports = Object.assign(createHook, {
NONCE_BYTES
})
module.exports = createHook
{
"name": "hypercore-xsalsa20-onwrite-hook",
"version": "1.0.2",
"version": "2.0.0",
"description": "A write hook to decrypt data using a XSalsa20 cipher into a hypercore storage when replicating from peers",

@@ -19,3 +19,3 @@ "main": "index.js",

"hypercore": "^8.0.0",
"hypercore-crypto": "^1.0.0",
"hypercore-indexed-file": "^0.1.3",
"hypercore-ready": "^0.2.0",

@@ -28,3 +28,5 @@ "hypercore-replicate": "^0.2.0",

"dependencies": {
"xsalsa20-encoding": "^1.0.1"
"hypercore-crypto": "^1.0.0",
"varint": "^5.0.0",
"xsalsa20-encoding": "^1.1.0"
},

@@ -31,0 +33,0 @@ "repository": {

@@ -16,4 +16,3 @@ hypercore-xsalsa20-onwrite-hook

```js
const nonces = ram() // or any `random-access-storage` compliant object
const onwrite = hook(nonces, sharedSecret)
const onwrite = hook(sharedSecret)
```

@@ -27,2 +26,3 @@

const crypto = require('hypercore-crypto')
const pump = require('pump')
const hook = require('hypercore-xsalsa20-onwrite-hook')

@@ -34,19 +34,36 @@ const ram = require('random-access-memory')

const { publicKey, secretKey } = crypto.keyPair()
const nonces = ram()
const feed = hypercore(ram, publicKey, {
const source = hypercore(ram, publicKey, {
secretKey,
onwrite: hook(nonces, key)
})
const copy = hypercore(ram, publicKey, {
onwrite: hook(nonces, key)
const cipher = hypercore(ram, publicKey, {
secretKey,
onwrite: hook(key)
})
feed.append(Buffer.from('hello'), (err) => {
feed.head(console.log) // ciphertext
const edge = hypercore(ram, publicKey)
const reader = hypercore(ram, publicKey, {
onwrite: hook(key)
})
replicate(feed, copy, (err) => {
copy.head(console.log) // plaintext
source.append(Buffer.from('hello'), (err) => {
source.head(console.log) // plaintext
// load cipher hypercore
pump(source.createReadStream(), cipher.createWriteStream(), (err) => {
if (err) throw err
cipher.head(console.log) // ciphertext
replicate(cipher, edge, (err) => {
if (err) throw err
edge.head(console.log) // ciphertext
replicate(edge, reader, (err) => {
if (err) throw err
reader.head(console.log) // plaintext
})
})
})
})

@@ -61,13 +78,7 @@ ```

xsalsa20 cipher to encipher or decipher blocks in a Hypercore feed.
Blocks that are written to a Hypercore feed are encrypted detached
from the nonce used for encryption. Nonces are written to a user
supplied "nonce storage" which can be reused for deciphering blocks
appended to a Hypercore feed.
Nonces are computed from the Hypercore feed's public key and block
index.
This function preserves block sizes but requires an external storage
for nonces (`nonceStorage`). Users should provide a `random-access-storage`
compliant instance or a factory function that returns one.
## License
MIT

@@ -10,23 +10,22 @@ const replicate = require('hypercore-replicate')

function createHookTest(storage, key) {
return (t) => {
const message = Buffer.from('hello')
const onwrite = hook(storage, key)
const feed = hypercore(ram, { onwrite })
feed.ready(() => {
// use `Buffer.from()` to make copy as `feed.append()`
// will modify `buffer` in place
feed.append(Buffer.from(message), (err) => {
const onwrite = hook(storage, key) // shadow
const authenticated = hypercore(ram, feed.key, { onwrite })
const unauthenticated = hypercore(ram, feed.key)
ready(authenticated, unauthenticated, () => {
replicate(feed, authenticated, unauthenticated, (err) => {
authenticated.head((err, buf) => {
t.ok(0 === Buffer.compare(buf, message), 'authenticated message')
test('createHook(key)', (t) => {
const key = crypto.randomBytes(32)
const message = Buffer.from('hello')
const onwrite = hook(key)
const feed = hypercore(ram, { onwrite })
feed.ready(() => {
// use `Buffer.from()` to make copy as `feed.append()`
// will modify `buffer` in place
feed.append(Buffer.from(message), (err) => {
const onwrite = hook(key) // shadow
const authenticated = hypercore(ram, feed.key, { onwrite })
const unauthenticated = hypercore(ram, feed.key)
ready(authenticated, unauthenticated, () => {
replicate(feed, authenticated, unauthenticated, (err) => {
authenticated.head((err, buf) => {
t.ok(0 === Buffer.compare(buf, message), 'authenticated message')
unauthenticated.head((err, buf) => {
t.ok(0 !== Buffer.compare(buf, message), 'unauthenticated message')
t.end()
})
unauthenticated.head((err, buf) => {
t.ok(0 !== Buffer.compare(buf, message), 'unauthenticated message')
t.end()
})

@@ -37,22 +36,3 @@ })

})
}
}
test('createHook(createStorage, key)', (t) => {
const storage = ram()
const key = crypto.randomBytes(32)
createHookTest(storage, key)(t)
})
})
test('createHook(createStorage, key) - storage factory', (t) => {
const storage = ram()
const key = crypto.randomBytes(32).toString('hex')
createHookTest(factory, key)(t)
function factory(opts, k) {
t.ok('object' === typeof opts)
t.ok(0 === Buffer.compare(
Buffer.from(k, 'hex'),
Buffer.from(key, 'hex')))
return storage
}
})
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