Skip to content
This repository has been archived by the owner on Jul 21, 2023. It is now read-only.

Commit

Permalink
fix: add buffer and update deps (#25)
Browse files Browse the repository at this point in the history
* fix: add buffer and update deps

update secp256k1 dep and fix code
use multibase to encode b58
avoid un-necessary circular dependency no libp2p-crypto
use  only sha256 from multihashing-async

* Update src/crypto.js

Co-Authored-By: Jacob Heun <jacobheun@gmail.com>

* chore: remove commitlint from CI

Co-authored-by: Jacob Heun <jacobheun@gmail.com>
  • Loading branch information
hugomrdias and jacobheun authored Mar 17, 2020
1 parent ae109d4 commit 35f196e
Show file tree
Hide file tree
Showing 7 changed files with 50 additions and 36 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ build
node_modules

dist
docs
package-lock.json
yarn.lock
.vscode
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ stages:

node_js:
- '10'
- '12'

os:
- linux
Expand All @@ -23,7 +24,6 @@ jobs:
include:
- stage: check
script:
- npx aegir commitlint --travis
- npx aegir dep-check
- npm run lint

Expand Down
16 changes: 7 additions & 9 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@
"description": "Support for secp256k1 keys in libp2p-crypto",
"leadMaintainer": "Friedel Ziegelmayer <dignifiedquire@gmail.com>",
"main": "src/index.js",
"browser": {
"secp256k1": "secp256k1/js"
},
"scripts": {
"lint": "aegir lint",
"build": "aegir build",
Expand All @@ -27,18 +24,19 @@
],
"license": "MIT",
"dependencies": {
"bs58": "^4.0.1",
"multihashing-async": "^0.8.0",
"nodeify": "^1.0.1",
"safe-buffer": "^5.1.2",
"secp256k1": "^3.6.2"
"buffer": "^5.5.0",
"is-typedarray": "^1.0.0",
"multibase": "^0.6.0",
"multihashing-async": "^0.8.1",
"secp256k1": "^4.0.0"
},
"devDependencies": {
"aegir": "^21.0.2",
"benchmark": "^2.1.4",
"chai": "^4.2.0",
"dirty-chai": "^2.0.1",
"libp2p-crypto": "~0.17.2"
"libp2p-crypto": "~0.17.2",
"protons": "^1.1.0"
},
"engines": {
"node": ">=6.0.0",
Expand Down
38 changes: 27 additions & 11 deletions src/crypto.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,26 @@
'use strict'

const { Buffer } = require('buffer')
var isTypedArray = require('is-typedarray').strict
const secp256k1 = require('secp256k1')
const multihashing = require('multihashing-async')

const sha = require('multihashing-async/src/sha')
const HASH_ALGORITHM = 'sha2-256'

function typedArrayTobuffer (arr) {
if (isTypedArray(arr)) {
// To avoid a copy, use the typed array's underlying ArrayBuffer to back new Buffer
var buf = Buffer.from(arr.buffer)
if (arr.byteLength !== arr.buffer.byteLength) {
// Respect the "view", i.e. byteOffset and byteLength, without doing a copy
buf = buf.slice(arr.byteOffset, arr.byteOffset + arr.byteLength)
}
return buf
} else {
// Pass through all other types to `Buffer.from`
return Buffer.from(arr)
}
}

module.exports = (randomBytes) => {
const privateKeyLength = 32

Expand All @@ -17,26 +33,26 @@ module.exports = (randomBytes) => {
}

async function hashAndSign (key, msg) {
const digest = await multihashing.digest(msg, HASH_ALGORITHM)
const sig = secp256k1.sign(digest, key)
return secp256k1.signatureExport(sig.signature)
const digest = await sha.digest(msg, HASH_ALGORITHM)
const sig = secp256k1.ecdsaSign(digest, key)
return typedArrayTobuffer(secp256k1.signatureExport(sig.signature))
}

async function hashAndVerify (key, sig, msg) {
const digest = await multihashing.digest(msg, HASH_ALGORITHM)
sig = secp256k1.signatureImport(sig)
return secp256k1.verify(digest, sig, key)
const digest = await sha.digest(msg, HASH_ALGORITHM)
sig = typedArrayTobuffer(secp256k1.signatureImport(sig))
return secp256k1.ecdsaVerify(sig, digest, key)
}

function compressPublicKey (key) {
if (!secp256k1.publicKeyVerify(key)) {
throw new Error('Invalid public key')
}
return secp256k1.publicKeyConvert(key, true)
return typedArrayTobuffer(secp256k1.publicKeyConvert(key, true))
}

function decompressPublicKey (key) {
return secp256k1.publicKeyConvert(key, false)
return typedArrayTobuffer(secp256k1.publicKeyConvert(key, false))
}

function validatePrivateKey (key) {
Expand All @@ -53,7 +69,7 @@ module.exports = (randomBytes) => {

function computePublicKey (privateKey) {
validatePrivateKey(privateKey)
return secp256k1.publicKeyCreate(privateKey)
return typedArrayTobuffer(secp256k1.publicKeyCreate(privateKey))
}

return {
Expand Down
11 changes: 5 additions & 6 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use strict'

const bs58 = require('bs58')
const multihashing = require('multihashing-async')
const multibase = require('multibase')
const sha = require('multihashing-async/src/sha')

module.exports = (keysProtobuf, randomBytes, crypto) => {
crypto = crypto || require('./crypto')(randomBytes)
Expand Down Expand Up @@ -32,7 +32,7 @@ module.exports = (keysProtobuf, randomBytes, crypto) => {
}

hash () {
return multihashing(this.bytes, 'sha2-256')
return sha.multihashing(this.bytes, 'sha2-256')
}
}

Expand Down Expand Up @@ -68,7 +68,7 @@ module.exports = (keysProtobuf, randomBytes, crypto) => {
}

hash () {
return multihashing(this.bytes, 'sha2-256')
return sha.multihashing(this.bytes, 'sha2-256')
}

/**
Expand All @@ -83,8 +83,7 @@ module.exports = (keysProtobuf, randomBytes, crypto) => {
*/
async id () {
const hash = await this.public.hash()

return bs58.encode(hash)
return multibase.encode('base58btc', hash).toString().slice(1)
}
}

Expand Down
2 changes: 1 addition & 1 deletion test/fixtures/go-interop.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use strict'

const Buffer = require('safe-buffer').Buffer
const { Buffer } = require('buffer')

// The keypair and signature below were generated in a gore repl session (https://github.com/motemen/gore)
// using the secp256k1 fork of go-libp2p-crypto by github user @vyzo
Expand Down
16 changes: 8 additions & 8 deletions test/secp256k1.spec.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
/* eslint-env mocha */
'use strict'

const { Buffer } = require('buffer')
const chai = require('chai')
const dirtyChai = require('dirty-chai')
const expect = chai.expect
chai.use(dirtyChai)

const libp2pCrypto = require('libp2p-crypto')
const keysPBM = libp2pCrypto.keys.keysPBM
const randomBytes = libp2pCrypto.randomBytes
const protobuf = require('protons')
const keysPBM = protobuf(require('libp2p-crypto/src/keys/keys.proto'))
const randomBytes = require('libp2p-crypto/src/random-bytes')
const crypto = require('../src/crypto')(randomBytes)

describe('secp256k1 keys', () => {
Expand Down Expand Up @@ -136,7 +136,7 @@ describe('handles generation of invalid key', () => {
try {
await secp256k1.generateKeyPair()
} catch (err) {
return expect(err.message).to.equal('Invalid private key')
return expect(err.message).to.equal('Expected private key to be an Uint8Array with length 32')
}
throw new Error('Expected error to be thrown')
})
Expand Down Expand Up @@ -182,7 +182,7 @@ describe('crypto functions', () => {
try {
await crypto.hashAndSign(Buffer.from('42'), Buffer.from('Hello'))
} catch (err) {
return expect(err.message).to.equal('private key length is invalid')
return expect(err.message).to.equal('Expected private key to be an Uint8Array with length 32')
}
throw new Error('Expected error to be thrown')
})
Expand All @@ -202,7 +202,7 @@ describe('crypto functions', () => {
try {
await crypto.hashAndVerify(pubKey, Buffer.from('invalid-sig'), Buffer.from('hello'))
} catch (err) {
return expect(err.message).to.equal('couldn\'t parse DER signature')
return expect(err.message).to.equal('Signature could not be parsed')
}
throw new Error('Expected error to be thrown')
})
Expand All @@ -211,7 +211,7 @@ describe('crypto functions', () => {
try {
await crypto.hashAndSign(Buffer.from('42'), Buffer.from('Hello'))
} catch (err) {
return expect(err.message).to.equal('private key length is invalid')
return expect(err.message).to.equal('Expected private key to be an Uint8Array with length 32')
}
throw new Error('Expected error to be thrown')
})
Expand Down

0 comments on commit 35f196e

Please sign in to comment.