diff --git a/package.json b/package.json index 7cf8a2af..6d6baa53 100644 --- a/package.json +++ b/package.json @@ -148,6 +148,11 @@ "types": "./dist/types/src/hashes/interface.d.ts", "import": "./src/hashes/interface.js" }, + "./hashes/sha1": { + "types": "./dist/types/src/hashes/sha1.d.ts", + "browser": "./src/hashes/sha1-browser.js", + "import": "./src/hashes/sha1.js" + }, "./hashes/sha2": { "types": "./dist/types/src/hashes/sha2.d.ts", "browser": "./src/hashes/sha2-browser.js", @@ -171,6 +176,8 @@ } }, "browser": { + "./hashes/sha1": "./src/hashes/sha1-browser.js", + "./src/hashes/sha1.js": "./src/hashes/sha1-browser.js", "./hashes/sha2": "./src/hashes/sha2-browser.js", "./src/hashes/sha2.js": "./src/hashes/sha2-browser.js" }, @@ -286,7 +293,8 @@ "@types/node": "^18.0.0", "aegir": "^37.7.5", "buffer": "^6.0.3", - "cids": "^1.1.9" + "cids": "^1.1.9", + "crypto-hash": "^2.0.1" }, "aegir": { "test": { diff --git a/src/hashes/sha1-browser.js b/src/hashes/sha1-browser.js new file mode 100644 index 00000000..187ba543 --- /dev/null +++ b/src/hashes/sha1-browser.js @@ -0,0 +1,18 @@ +/* global crypto */ + +import { from } from './hasher.js' + +/** + * @param {AlgorithmIdentifier} name + */ +const sha = name => + /** + * @param {Uint8Array} data + */ + async data => new Uint8Array(await crypto.subtle.digest(name, data)) + +export const sha1 = from({ + name: 'sha-1', + code: 0x11, + encode: sha('SHA-1') +}) diff --git a/src/hashes/sha1.js b/src/hashes/sha1.js new file mode 100644 index 00000000..2146227b --- /dev/null +++ b/src/hashes/sha1.js @@ -0,0 +1,11 @@ +// @ts-check + +import crypto from 'crypto' +import { from } from './hasher.js' +import { coerce } from '../bytes.js' + +export const sha1 = from({ + name: 'sha-1', + code: 0x11, + encode: (input) => coerce(crypto.createHash('sha1').update(input).digest()) +}) diff --git a/test/test-multihash.spec.js b/test/test-multihash.spec.js index 87126137..a074a98f 100644 --- a/test/test-multihash.spec.js +++ b/test/test-multihash.spec.js @@ -1,10 +1,12 @@ /* globals describe, it */ import { fromHex, fromString } from '../src/bytes.js' import { sha256, sha512 } from '../src/hashes/sha2.js' +import { sha1 } from '../src/hashes/sha1.js' import { identity } from '../src/hashes/identity.js' import { decode as decodeDigest, create as createDigest } from '../src/hashes/digest.js' import valid from './fixtures/valid-multihash.js' import invalid from './fixtures/invalid-multihash.js' +import { sha1 as chSha1 } from 'crypto-hash' import { hash as slSha256 } from '@stablelib/sha256' import { hash as slSha512 } from '@stablelib/sha512' import { assert } from 'aegir/chai' @@ -39,6 +41,32 @@ describe('multihash', () => { } }) + it('hash sha1', async () => { + const hash = await sha1.digest(fromString('test')) + assert.deepStrictEqual(hash.code, sha1.code) + assert.deepStrictEqual(hash.digest, fromHex(await chSha1(fromString('test')))) + + const hash2 = decodeDigest(hash.bytes) + assert.deepStrictEqual(hash2.code, sha1.code) + assert.deepStrictEqual(hash2.bytes, hash.bytes) + }) + + if (typeof navigator === 'undefined') { + it('sync sha1', async () => { + const hash = sha1.digest(fromString('test')) + if (hash instanceof Promise) { + assert.fail('expected sync result') + } else { + assert.deepStrictEqual(hash.code, sha1.code) + assert.deepStrictEqual(hash.digest, fromHex(await chSha1(fromString('test')))) + + const hash2 = decodeDigest(hash.bytes) + assert.deepStrictEqual(hash2.code, sha1.code) + assert.deepStrictEqual(hash2.bytes, hash.bytes) + } + }) + } + it('hash sha2-256', async () => { const hash = await sha256.digest(fromString('test')) assert.deepStrictEqual(hash.code, sha256.code)