UNPKG

@erasure/crypto-ipfs

Version:

asymmetric and symmetric crypto for use with erasure, ipfs and private backend. warning: unaudited.

342 lines (311 loc) 11.2 kB
const assert = require('assert') const isBase64 = require('is-base64') const ErasureHelper = require('../index') describe('multihash', () => { describe('test inputs', () => { it('should correctly parse a b58 multihash', async () => { const hash = await ErasureHelper.multihash({ input: 'QmQfJQtxGA5MzWi5HZPyCaZiPAzNkxq8U9yApihkKsWZx2', inputType: 'b58', outputType: 'hex', }) assert.equal( hash, '0x1220227e75ab3fb8ba90fbb7addb3d30bd20c676f873e0216a767084b2073e0b7d9f', ) }) it('should correctly parse a hex multihash with 0x prefix', async () => { const hash = await ErasureHelper.multihash({ input: '0x1220227e75ab3fb8ba90fbb7addb3d30bd20c676f873e0216a767084b2073e0b7d9f', inputType: 'hex', outputType: 'b58', }) assert.equal(hash, 'QmQfJQtxGA5MzWi5HZPyCaZiPAzNkxq8U9yApihkKsWZx2') }) it('should correctly parse a hex multihash', async () => { const hash = await ErasureHelper.multihash({ input: '1220227e75ab3fb8ba90fbb7addb3d30bd20c676f873e0216a767084b2073e0b7d9f', inputType: 'hex', outputType: 'b58', }) assert.equal(hash, 'QmQfJQtxGA5MzWi5HZPyCaZiPAzNkxq8U9yApihkKsWZx2') }) it('should correctly parse a sha2-256 with 0x prefix', async () => { const hash = await ErasureHelper.multihash({ input: '0x227e75ab3fb8ba90fbb7addb3d30bd20c676f873e0216a767084b2073e0b7d9f', inputType: 'sha2-256', outputType: 'b58', }) assert.equal(hash, 'QmQfJQtxGA5MzWi5HZPyCaZiPAzNkxq8U9yApihkKsWZx2') }) it('should correctly parse a sha2-256', async () => { const hash = await ErasureHelper.multihash({ input: '227e75ab3fb8ba90fbb7addb3d30bd20c676f873e0216a767084b2073e0b7d9f', inputType: 'sha2-256', outputType: 'b58', }) assert.equal(hash, 'QmQfJQtxGA5MzWi5HZPyCaZiPAzNkxq8U9yApihkKsWZx2') }) it('should calculate the multihash of a string', async () => { const hash = await ErasureHelper.multihash({ input: 'Hello World!\n', inputType: 'raw', outputType: 'b58', }) assert.equal(hash, 'QmfM2r8seH2GiRaC4esTjeraXEachRt8ZsSeGaWTPLyMoG') }) it('should calculate the multihash of a buffer', async () => { const hash = await ErasureHelper.multihash({ input: Buffer.from('Hello World!\n'), inputType: 'raw', outputType: 'b58', }) assert.equal(hash, 'QmfM2r8seH2GiRaC4esTjeraXEachRt8ZsSeGaWTPLyMoG') }) it('should calculate the multihash of a JSON', async () => { const hash = await ErasureHelper.multihash({ input: JSON.stringify({ proofhash: 'hello' }), inputType: 'raw', outputType: 'b58', }) assert.equal(hash, 'QmbYQZq5qF6D4mfnB4ahpBqr8HfzyjJDcYk6cszRbNwkhs') }) }) describe('test outputs', () => { it('should output correct prefix', async () => { const hash = await ErasureHelper.multihash({ input: 'QmQfJQtxGA5MzWi5HZPyCaZiPAzNkxq8U9yApihkKsWZx2', inputType: 'b58', outputType: 'prefix', }) assert.equal(hash, '0x1220') }) it('should output correct digest', async () => { const hash = await ErasureHelper.multihash({ input: 'QmQfJQtxGA5MzWi5HZPyCaZiPAzNkxq8U9yApihkKsWZx2', inputType: 'b58', outputType: 'digest', }) assert.equal( hash, '0x227e75ab3fb8ba90fbb7addb3d30bd20c676f873e0216a767084b2073e0b7d9f', ) }) it('should output correct hex', async () => { const hash = await ErasureHelper.multihash({ input: 'QmQfJQtxGA5MzWi5HZPyCaZiPAzNkxq8U9yApihkKsWZx2', inputType: 'b58', outputType: 'hex', }) assert.equal( hash, '0x1220227e75ab3fb8ba90fbb7addb3d30bd20c676f873e0216a767084b2073e0b7d9f', ) }) it('should output correct b58', async () => { const hash = await ErasureHelper.multihash({ input: 'QmQfJQtxGA5MzWi5HZPyCaZiPAzNkxq8U9yApihkKsWZx2', inputType: 'b58', outputType: 'b58', }) assert.equal(hash, 'QmQfJQtxGA5MzWi5HZPyCaZiPAzNkxq8U9yApihkKsWZx2') }) }) }) describe('encodeCreateCall', () => { it('should encode initialize function call', () => { const abi = [ { constant: false, inputs: [ { internalType: 'address', name: 'operator', type: 'address', }, { internalType: 'bytes', name: 'metadata', type: 'bytes', }, ], name: 'initialize', outputs: [], payable: false, stateMutability: 'nonpayable', type: 'function', }, ] const values = [ '0x6B175474E89094C44Da98b954EedeAC495271d0F', '0x1220227e75ab3fb8ba90fbb7addb3d30bd20c676f873e0216a767084b2073e0b7d9f', ] const call = ErasureHelper.encodeCreateCall(abi, values) assert.equal( call, '0xd1f578940000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000221220227e75ab3fb8ba90fbb7addb3d30bd20c676f873e0216a767084b2073e0b7d9f000000000000000000000000000000000000000000000000000000000000', ) }) }) describe('crypto', () => { describe('symmetric', () => { describe('generateKey', () => { it('should return a base64 string of length 44', () => { const key = ErasureHelper.crypto.symmetric.generateKey() assert.equal(key.length, 44) assert(isBase64(key)) }) }) describe('encryptMessage and decryptMessage', () => { it('should encrypt and decrypt a message with one key', () => { const key1 = ErasureHelper.crypto.symmetric.generateKey() const key2 = ErasureHelper.crypto.symmetric.generateKey() const msg = 'this is a message' const encryptedMessage = ErasureHelper.crypto.symmetric.encryptMessage( key1, msg, ) const decryptedMessage = ErasureHelper.crypto.symmetric.decryptMessage( key1, encryptedMessage, ) assert.equal(decryptedMessage, msg) assert.throws( () => ErasureHelper.crypto.symmetric.decryptMessage( key2, encryptedMessage, ), Error, 'error thrown', ) }) }) }) describe('asymmetric', () => { describe('generateKeyPair', () => { it('should generate a public and private key', () => { const sig = 'this is a password or web3 signature' const salt = "this is a salt, which could be generated server side and stored on user table. only authenticated users should be able to GET their own salt from the server and nobody else's." const keypair = ErasureHelper.crypto.asymmetric.generateKeyPair( sig, salt, ) assert(keypair.publicKey instanceof Uint8Array) assert.equal(keypair.publicKey.length, 32) assert(keypair.secretKey instanceof Uint8Array) assert.equal(keypair.secretKey.length, 32) }) }) describe('generateNonce', () => { it('should generate a nonce', () => { const nonce = ErasureHelper.crypto.asymmetric.generateNonce() assert(nonce instanceof Uint8Array) assert.equal(nonce.length, 24) }) }) describe('encryptMessage and decryptMessage', () => { it('should enable bob and alice (not charlie) to share a secret', () => { const nonce = ErasureHelper.crypto.asymmetric.generateNonce() const bobSig = 'bob signature' const bobSalt = 'bob salt' const bobKeypair = ErasureHelper.crypto.asymmetric.generateKeyPair( bobSig, bobSalt, ) const aliceSig = 'alice signature' const aliceSalt = 'alice salt' const aliceKeypair = ErasureHelper.crypto.asymmetric.generateKeyPair( aliceSig, aliceSalt, ) const charlieSig = 'charlie signature' const charlieSalt = 'charlie salt' const charlieKeypair = ErasureHelper.crypto.asymmetric.generateKeyPair( charlieSig, charlieSalt, ) const msg = 'secret from bob to alice' const encryptedMessage = ErasureHelper.crypto.asymmetric.encryptMessage( msg, nonce, aliceKeypair.publicKey, bobKeypair.secretKey, ) const decryptedByAlice = ErasureHelper.crypto.asymmetric.decryptMessage( encryptedMessage, nonce, bobKeypair.publicKey, aliceKeypair.secretKey, ) assert.equal(decryptedByAlice, msg) const decryptedByBob = ErasureHelper.crypto.asymmetric.decryptMessage( encryptedMessage, nonce, aliceKeypair.publicKey, bobKeypair.secretKey, ) assert.equal(decryptedByBob, msg) assert.throws(() => { const decryptedByCharlieAttempt1 = ErasureHelper.crypto.asymmetric.decryptMessage( encryptedMessage, nonce, bobKeypair.publicKey, charlieKeypair.secretKey, ) }) assert.throws(() => { const decryptedByCharlieAttempt2 = ErasureHelper.crypto.asymmetric.decryptMessage( encryptedMessage, nonce, aliceKeypair.publicKey, charlieKeypair.secretKey, ) }) }) }) describe('secretBox', () => { describe('encryptMessage and decryptMessage', () => { it('should encrypt and decrypt a message to/from bob and no one else', () => { const nonce = ErasureHelper.crypto.asymmetric.generateNonce() const bobSig = 'bob signature' const bobSalt = 'bob salt' const bobKeypair = ErasureHelper.crypto.asymmetric.generateKeyPair( bobSig, bobSalt, ) const charlieSig = 'charlie signature' const charlieSalt = 'charlie salt' const charlieKeypair = ErasureHelper.crypto.asymmetric.generateKeyPair( charlieSig, charlieSalt, ) const msg = 'secret from bob to bob' const encryptedMessage = ErasureHelper.crypto.asymmetric.secretBox.encryptMessage( msg, nonce, bobKeypair.secretKey, ) const decryptedByBob = ErasureHelper.crypto.asymmetric.secretBox.decryptMessage( encryptedMessage, nonce, bobKeypair.secretKey, ) assert.equal(decryptedByBob, msg) assert.throws(() => { const decryptedByCharlieAttempt = ErasureHelper.crypto.asymmetric.secretBox.decryptMessage( encryptedMessage, nonce, charlieKeypair.secretKey, ) }) }) }) }) }) })