mirror of
https://github.com/fluencelabs/js-libp2p-crypto
synced 2025-03-15 09:41:03 +00:00
fix: add buffer and update deps (#25)
* 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>
This commit is contained in:
parent
ae109d46f7
commit
35f196ea4d
1
.gitignore
vendored
1
.gitignore
vendored
@ -32,6 +32,7 @@ build
|
|||||||
node_modules
|
node_modules
|
||||||
|
|
||||||
dist
|
dist
|
||||||
|
docs
|
||||||
package-lock.json
|
package-lock.json
|
||||||
yarn.lock
|
yarn.lock
|
||||||
.vscode
|
.vscode
|
||||||
|
@ -10,6 +10,7 @@ stages:
|
|||||||
|
|
||||||
node_js:
|
node_js:
|
||||||
- '10'
|
- '10'
|
||||||
|
- '12'
|
||||||
|
|
||||||
os:
|
os:
|
||||||
- linux
|
- linux
|
||||||
@ -23,7 +24,6 @@ jobs:
|
|||||||
include:
|
include:
|
||||||
- stage: check
|
- stage: check
|
||||||
script:
|
script:
|
||||||
- npx aegir commitlint --travis
|
|
||||||
- npx aegir dep-check
|
- npx aegir dep-check
|
||||||
- npm run lint
|
- npm run lint
|
||||||
|
|
||||||
|
16
package.json
16
package.json
@ -4,9 +4,6 @@
|
|||||||
"description": "Support for secp256k1 keys in libp2p-crypto",
|
"description": "Support for secp256k1 keys in libp2p-crypto",
|
||||||
"leadMaintainer": "Friedel Ziegelmayer <dignifiedquire@gmail.com>",
|
"leadMaintainer": "Friedel Ziegelmayer <dignifiedquire@gmail.com>",
|
||||||
"main": "src/index.js",
|
"main": "src/index.js",
|
||||||
"browser": {
|
|
||||||
"secp256k1": "secp256k1/js"
|
|
||||||
},
|
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"lint": "aegir lint",
|
"lint": "aegir lint",
|
||||||
"build": "aegir build",
|
"build": "aegir build",
|
||||||
@ -27,18 +24,19 @@
|
|||||||
],
|
],
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"bs58": "^4.0.1",
|
"buffer": "^5.5.0",
|
||||||
"multihashing-async": "^0.8.0",
|
"is-typedarray": "^1.0.0",
|
||||||
"nodeify": "^1.0.1",
|
"multibase": "^0.6.0",
|
||||||
"safe-buffer": "^5.1.2",
|
"multihashing-async": "^0.8.1",
|
||||||
"secp256k1": "^3.6.2"
|
"secp256k1": "^4.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"aegir": "^21.0.2",
|
"aegir": "^21.0.2",
|
||||||
"benchmark": "^2.1.4",
|
"benchmark": "^2.1.4",
|
||||||
"chai": "^4.2.0",
|
"chai": "^4.2.0",
|
||||||
"dirty-chai": "^2.0.1",
|
"dirty-chai": "^2.0.1",
|
||||||
"libp2p-crypto": "~0.17.2"
|
"libp2p-crypto": "~0.17.2",
|
||||||
|
"protons": "^1.1.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.0.0",
|
"node": ">=6.0.0",
|
||||||
|
@ -1,10 +1,26 @@
|
|||||||
'use strict'
|
'use strict'
|
||||||
|
|
||||||
|
const { Buffer } = require('buffer')
|
||||||
|
var isTypedArray = require('is-typedarray').strict
|
||||||
const secp256k1 = require('secp256k1')
|
const secp256k1 = require('secp256k1')
|
||||||
const multihashing = require('multihashing-async')
|
const sha = require('multihashing-async/src/sha')
|
||||||
|
|
||||||
const HASH_ALGORITHM = 'sha2-256'
|
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) => {
|
module.exports = (randomBytes) => {
|
||||||
const privateKeyLength = 32
|
const privateKeyLength = 32
|
||||||
|
|
||||||
@ -17,26 +33,26 @@ module.exports = (randomBytes) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function hashAndSign (key, msg) {
|
async function hashAndSign (key, msg) {
|
||||||
const digest = await multihashing.digest(msg, HASH_ALGORITHM)
|
const digest = await sha.digest(msg, HASH_ALGORITHM)
|
||||||
const sig = secp256k1.sign(digest, key)
|
const sig = secp256k1.ecdsaSign(digest, key)
|
||||||
return secp256k1.signatureExport(sig.signature)
|
return typedArrayTobuffer(secp256k1.signatureExport(sig.signature))
|
||||||
}
|
}
|
||||||
|
|
||||||
async function hashAndVerify (key, sig, msg) {
|
async function hashAndVerify (key, sig, msg) {
|
||||||
const digest = await multihashing.digest(msg, HASH_ALGORITHM)
|
const digest = await sha.digest(msg, HASH_ALGORITHM)
|
||||||
sig = secp256k1.signatureImport(sig)
|
sig = typedArrayTobuffer(secp256k1.signatureImport(sig))
|
||||||
return secp256k1.verify(digest, sig, key)
|
return secp256k1.ecdsaVerify(sig, digest, key)
|
||||||
}
|
}
|
||||||
|
|
||||||
function compressPublicKey (key) {
|
function compressPublicKey (key) {
|
||||||
if (!secp256k1.publicKeyVerify(key)) {
|
if (!secp256k1.publicKeyVerify(key)) {
|
||||||
throw new Error('Invalid public key')
|
throw new Error('Invalid public key')
|
||||||
}
|
}
|
||||||
return secp256k1.publicKeyConvert(key, true)
|
return typedArrayTobuffer(secp256k1.publicKeyConvert(key, true))
|
||||||
}
|
}
|
||||||
|
|
||||||
function decompressPublicKey (key) {
|
function decompressPublicKey (key) {
|
||||||
return secp256k1.publicKeyConvert(key, false)
|
return typedArrayTobuffer(secp256k1.publicKeyConvert(key, false))
|
||||||
}
|
}
|
||||||
|
|
||||||
function validatePrivateKey (key) {
|
function validatePrivateKey (key) {
|
||||||
@ -53,7 +69,7 @@ module.exports = (randomBytes) => {
|
|||||||
|
|
||||||
function computePublicKey (privateKey) {
|
function computePublicKey (privateKey) {
|
||||||
validatePrivateKey(privateKey)
|
validatePrivateKey(privateKey)
|
||||||
return secp256k1.publicKeyCreate(privateKey)
|
return typedArrayTobuffer(secp256k1.publicKeyCreate(privateKey))
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
11
src/index.js
11
src/index.js
@ -1,7 +1,7 @@
|
|||||||
'use strict'
|
'use strict'
|
||||||
|
|
||||||
const bs58 = require('bs58')
|
const multibase = require('multibase')
|
||||||
const multihashing = require('multihashing-async')
|
const sha = require('multihashing-async/src/sha')
|
||||||
|
|
||||||
module.exports = (keysProtobuf, randomBytes, crypto) => {
|
module.exports = (keysProtobuf, randomBytes, crypto) => {
|
||||||
crypto = crypto || require('./crypto')(randomBytes)
|
crypto = crypto || require('./crypto')(randomBytes)
|
||||||
@ -32,7 +32,7 @@ module.exports = (keysProtobuf, randomBytes, crypto) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
hash () {
|
hash () {
|
||||||
return multihashing(this.bytes, 'sha2-256')
|
return sha.multihashing(this.bytes, 'sha2-256')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,7 +68,7 @@ module.exports = (keysProtobuf, randomBytes, crypto) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
hash () {
|
hash () {
|
||||||
return multihashing(this.bytes, 'sha2-256')
|
return sha.multihashing(this.bytes, 'sha2-256')
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -83,8 +83,7 @@ module.exports = (keysProtobuf, randomBytes, crypto) => {
|
|||||||
*/
|
*/
|
||||||
async id () {
|
async id () {
|
||||||
const hash = await this.public.hash()
|
const hash = await this.public.hash()
|
||||||
|
return multibase.encode('base58btc', hash).toString().slice(1)
|
||||||
return bs58.encode(hash)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
2
test/fixtures/go-interop.js
vendored
2
test/fixtures/go-interop.js
vendored
@ -1,6 +1,6 @@
|
|||||||
'use strict'
|
'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)
|
// 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
|
// using the secp256k1 fork of go-libp2p-crypto by github user @vyzo
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
/* eslint-env mocha */
|
/* eslint-env mocha */
|
||||||
'use strict'
|
'use strict'
|
||||||
|
|
||||||
|
const { Buffer } = require('buffer')
|
||||||
const chai = require('chai')
|
const chai = require('chai')
|
||||||
const dirtyChai = require('dirty-chai')
|
const dirtyChai = require('dirty-chai')
|
||||||
const expect = chai.expect
|
const expect = chai.expect
|
||||||
chai.use(dirtyChai)
|
chai.use(dirtyChai)
|
||||||
|
const protobuf = require('protons')
|
||||||
const libp2pCrypto = require('libp2p-crypto')
|
const keysPBM = protobuf(require('libp2p-crypto/src/keys/keys.proto'))
|
||||||
const keysPBM = libp2pCrypto.keys.keysPBM
|
const randomBytes = require('libp2p-crypto/src/random-bytes')
|
||||||
const randomBytes = libp2pCrypto.randomBytes
|
|
||||||
const crypto = require('../src/crypto')(randomBytes)
|
const crypto = require('../src/crypto')(randomBytes)
|
||||||
|
|
||||||
describe('secp256k1 keys', () => {
|
describe('secp256k1 keys', () => {
|
||||||
@ -136,7 +136,7 @@ describe('handles generation of invalid key', () => {
|
|||||||
try {
|
try {
|
||||||
await secp256k1.generateKeyPair()
|
await secp256k1.generateKeyPair()
|
||||||
} catch (err) {
|
} 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')
|
throw new Error('Expected error to be thrown')
|
||||||
})
|
})
|
||||||
@ -182,7 +182,7 @@ describe('crypto functions', () => {
|
|||||||
try {
|
try {
|
||||||
await crypto.hashAndSign(Buffer.from('42'), Buffer.from('Hello'))
|
await crypto.hashAndSign(Buffer.from('42'), Buffer.from('Hello'))
|
||||||
} catch (err) {
|
} 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')
|
throw new Error('Expected error to be thrown')
|
||||||
})
|
})
|
||||||
@ -202,7 +202,7 @@ describe('crypto functions', () => {
|
|||||||
try {
|
try {
|
||||||
await crypto.hashAndVerify(pubKey, Buffer.from('invalid-sig'), Buffer.from('hello'))
|
await crypto.hashAndVerify(pubKey, Buffer.from('invalid-sig'), Buffer.from('hello'))
|
||||||
} catch (err) {
|
} 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')
|
throw new Error('Expected error to be thrown')
|
||||||
})
|
})
|
||||||
@ -211,7 +211,7 @@ describe('crypto functions', () => {
|
|||||||
try {
|
try {
|
||||||
await crypto.hashAndSign(Buffer.from('42'), Buffer.from('Hello'))
|
await crypto.hashAndSign(Buffer.from('42'), Buffer.from('Hello'))
|
||||||
} catch (err) {
|
} 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')
|
throw new Error('Expected error to be thrown')
|
||||||
})
|
})
|
||||||
|
Loading…
x
Reference in New Issue
Block a user