diff --git a/src/Binary.ts b/src/Binary.ts index a00109b..c2424a3 100644 --- a/src/Binary.ts +++ b/src/Binary.ts @@ -1,5 +1,6 @@ import { IBinary } from './types'; import { sha256 } from '@noble/hashes/sha256'; +import { hmac } from '@noble/hashes/hmac'; import { int16ToBytes, int32ToBytes } from './utils/bytes'; import { bytesToHex, hexToBytes } from '@noble/hashes/utils'; import { base58 } from '@scure/base'; @@ -27,11 +28,20 @@ export default class Binary extends Uint8Array implements IBinary { return bytesToHex(this); } + get dataView(): DataView { + return new DataView(this.buffer); + } + /** Create a SHA256 hash */ hash(): Binary { return new Binary(sha256(new Uint8Array(this))); } + /** Create HMAC SHA256 hash */ + hmac(key: string | Uint8Array): Binary { + return new Binary(hmac(sha256, key, this)); + } + toString(): string { return new TextDecoder().decode(this); } diff --git a/src/types/binary.d.ts b/src/types/binary.d.ts index 64e0dee..12dde8d 100644 --- a/src/types/binary.d.ts +++ b/src/types/binary.d.ts @@ -4,8 +4,10 @@ export interface IBinary extends Uint8Array { readonly base58: string; readonly base64: string; readonly hex: string; + readonly dataView: DataView; toString(): string; hash(): IBinary; + hmac(key: string | Uint8Array): IBinary; slice(start?: number, end?: number): IBinary; reverse(): IBinary; toReversed(): IBinary; diff --git a/src/utils/convert.ts b/src/utils/convert.ts index 29db500..18e1649 100644 --- a/src/utils/convert.ts +++ b/src/utils/convert.ts @@ -25,7 +25,7 @@ export function bytesToByteArrayWithSize(input: TBinary): Uint8Array { if (!(input instanceof Array)) input = Array.prototype.slice.call(input); - const lengthBytes = int16ToBytes(input.length); + const lengthBytes = shortToByteArray(input.length); return Uint8Array.from([...lengthBytes, ...(input as Array)]); } diff --git a/test/Binary.spec.ts b/test/Binary.spec.ts index c4dab4a..7cb9ca0 100644 --- a/test/Binary.spec.ts +++ b/test/Binary.spec.ts @@ -1,6 +1,7 @@ import { expect } from 'chai'; import { Binary } from '../src'; import { sha256 } from '@noble/hashes/sha256'; +import { hmac } from '@noble/hashes/hmac'; describe('Binary', () => { const testString = 'test'; @@ -69,6 +70,18 @@ describe('Binary', () => { }); }); + describe('dataview', () => { + it('should return correct dataview', () => { + const binary = Binary.concat(Binary.fromInt32(123), Binary.fromInt16(45)); + expect(binary.dataView).to.be.instanceOf(DataView); + expect(binary.dataView.byteLength).to.equal(6); + expect(binary.dataView.byteOffset).to.equal(0); + + expect(binary.dataView.getInt32(0)).to.be.deep.equal(123); + expect(binary.dataView.getInt16(4)).to.be.deep.equal(45); + }); + }); + describe('fromBase58', () => { it('should return correct Binary from base58 string', () => { const binary = Binary.fromBase58(base58String); @@ -177,4 +190,22 @@ describe('Binary', () => { expect(hash).to.deep.equal(sha256(testString)); }); }); + + describe('hmac', () => { + it('should return a Binary with the hmac sha256 hash with a string key', () => { + const binary = new Binary(testString); + const hash = binary.hmac('some_key'); + + expect(hash).to.be.instanceOf(Binary); + expect(hash).to.deep.equal(hmac(sha256, 'some_key', testString)); + }); + + it('should return a Binary with the hmac sha256 hash with a binary key', () => { + const binary = new Binary(testString); + const hash = binary.hmac(new Binary('some_key')); + + expect(hash).to.be.instanceOf(Binary); + expect(hash).to.deep.equal(hmac(sha256, 'some_key', testString)); + }); + }); });