UNPKG

@aeternity/aepp-sdk

Version:
146 lines (127 loc) 6.46 kB
/* * ISC License (ISC) * Copyright (c) 2018 aeternity developers * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ import '../' import { describe, it } from 'mocha' import { assert, expect } from 'chai' import * as Crypto from '../../es/utils/crypto' import { addressToHex, encodeBase58Check } from '../../es/utils/crypto' // These keys are fixations for the encryption lifecycle tests and will // not be used for signing const privateKeyAsHex = '4d881dd1917036cc231f9881a0db978c8899dd76a817252418606b02bf6ab9d22378f892b7cc82c2d2739e994ec9953aa36461f1eb5a4a49a5b0de17b3d23ae8' const privateKey = Buffer.from(privateKeyAsHex, 'hex') const publicKeyWithPrefix = 'ak_Gd6iMVsoonGuTF8LeswwDDN2NF5wYHAoTRtzwdEcfS32LWoxm' const publicKey = Buffer.from(Crypto.decodeBase58Check(publicKeyWithPrefix.split('_')[1])) const txBinaryAsArray = [248, 76, 12, 1, 160, 35, 120, 248, 146, 183, 204, 130, 194, 210, 115, 158, 153, 78, 201, 149, 58, 163, 100, 97, 241, 235, 90, 74, 73, 165, 176, 222, 23, 179, 210, 58, 232, 160, 63, 40, 35, 12, 40, 65, 38, 215, 218, 236, 136, 133, 42, 120, 160, 179, 18, 191, 241, 162, 198, 203, 209, 173, 89, 136, 202, 211, 158, 59, 12, 122, 1, 1, 1, 132, 84, 101, 115, 116] const txBinary = Buffer.from(txBinaryAsArray) const signatureAsArray = [95, 146, 31, 37, 95, 194, 36, 76, 58, 49, 167, 156, 127, 131, 142, 248, 25, 121, 139, 109, 59, 243, 203, 205, 16, 172, 115, 143, 254, 236, 33, 4, 43, 46, 16, 190, 46, 46, 140, 166, 76, 39, 249, 54, 38, 27, 93, 159, 58, 148, 67, 198, 81, 206, 106, 237, 91, 131, 27, 14, 143, 178, 130, 2] const signature = Buffer.from(signatureAsArray) describe('crypto', () => { describe('generateKeyPair', () => { it('generates an account key pair', () => { const keyPair = Crypto.generateKeyPair() assert.ok(keyPair) assert.isTrue(keyPair.publicKey.startsWith('ak_')) assert.isAtLeast(keyPair.publicKey.length, 51) assert.isAtMost(keyPair.publicKey.length, 53) }) }) describe('encryptPassword', () => { describe('generate a password encrypted key pair', () => { const keyPair = Crypto.generateKeyPair(true) const password = 'verysecret' it('works for private keys', () => { const privateBinary = keyPair.secretKey const encryptedPrivate = Crypto.encryptPrivateKey(password, privateBinary) const decryptedPrivate = Crypto.decryptPrivateKey(password, encryptedPrivate) assert.deepEqual(decryptedPrivate, privateBinary) }) it('works for public keys', () => { const publicBinary = keyPair.publicKey const encryptedPublic = Crypto.encryptPublicKey(password, publicBinary) const decryptedPublic = Crypto.decryptPubKey(password, encryptedPublic) assert.deepEqual(decryptedPublic, publicBinary) }) }) }) describe('encodeBase', () => { it('can be encoded and decoded', () => { const input = 'helloword010101023' const inputBuffer = Buffer.from(input) const encoded = Crypto.encodeBase58Check(inputBuffer) const decoded = Crypto.decodeBase58Check(encoded) assert.equal(input, decoded) }) }) describe('sign', () => { it('should produce correct signature', () => { const s = Crypto.sign(txBinary, privateKey) expect(s).to.eql(signature) }) }) describe('verify', () => { it('should verify tx with correct signature', () => { const result = Crypto.verify(txBinary, signature, publicKey) assert.isTrue(result) }) }) describe('personal messages', () => { const message = 'test' const messageSignatureAsHex = '20f779383f3ce0ab7781b7c8ff848e6d80f7f22d5cdc266763cd74d89c5ee0716758e75f56391711957f506d4993ae7dea62bec0f2806e6de66227f52836160a' const messageSignature = Buffer.from(messageSignatureAsHex, 'hex') const messageNonASCII = 'tæst' const messageNonASCIISignatureAsHex = '68d1344c46d9b2ef642490ffade3155c714471dd6d097fc393edc1004031a5492270de77ef8918df7857ea348d8ba4444ed1ff8e84f19e8e685e31174356fa06' const messageNonASCIISignature = Buffer.from(messageNonASCIISignatureAsHex, 'hex') describe('sign', () => { it('should produce correct signature of message', () => { const s = Crypto.signPersonalMessage(message, privateKey) expect(s).to.eql(messageSignature) }) it('should produce correct signature of message with non-ASCII chars', () => { const s = Crypto.signPersonalMessage(messageNonASCII, privateKey) expect(s).to.eql(messageNonASCIISignature) }) }) describe('verify', () => { it('should verify message', () => { const result = Crypto.verifyPersonalMessage(message, messageSignature, publicKey) assert.isTrue(result) }) it('should verify message with non-ASCII chars', () => { const result = Crypto.verifyPersonalMessage(messageNonASCII, messageNonASCIISignature, publicKey) assert.isTrue(result) }) }) }) it('hashing produces 256 bit blake2b byte buffers', () => { const hash = Crypto.hash('foobar') hash.should.be.a('Uint8Array') Buffer.from(hash).toString('hex').should.be.equal('93a0e84a8cdd4166267dbe1263e937f08087723ac24e7dcc35b3d5941775ef47') }) it('salt produces random sequences every time', () => { const salt1 = Crypto.salt() const salt2 = Crypto.salt() salt1.should.be.a('Number') salt2.should.be.a('Number') salt1.should.not.be.equal(salt2) }) it('Convert base58Check address to hex', () => { const address = 'ak_Gd6iMVsoonGuTF8LeswwDDN2NF5wYHAoTRtzwdEcfS32LWoxm' const hex = addressToHex(address) const fromHexAddress = 'ak_' + encodeBase58Check(Buffer.from(hex.slice(2), 'hex')) fromHexAddress.should.be.equal(address) }) })