Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions packages/crypto/src/coders/hex.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ const enum HexCharCode {
F_LO = 102 // f
}

/**
* Convert a Uint8Array to a hex string
* @param bytes
*/
function bytesToHex(bytes: Uint8Array): string {
assertInstanceOf(bytes, Uint8Array);

Expand All @@ -23,6 +27,10 @@ function bytesToHex(bytes: Uint8Array): string {
return hex;
}

/**
* Convert a hex string to a Uint8Array
* @param hex
*/
function hexToBytes(hex: string): Uint8Array {
assertTypeOf(hex, "string");
assert(hex.length % 2 === 0, "Invalid hex padding.");
Expand All @@ -37,6 +45,14 @@ function hexToBytes(hex: string): Uint8Array {
return bytes;
}

/**
* Convert a hex character code to a base 16 number
* @param char
*
* @example
* charCodeToBase16(48) // 0
* charCodeToBase16(57) // 9
*/
function charCodeToBase16(char: number) {
if (char >= HexCharCode.ZERO && char <= HexCharCode.NINE) {
return char - HexCharCode.ZERO;
Expand Down
12 changes: 12 additions & 0 deletions packages/crypto/src/coders/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ import { describe, expect, test } from "vitest";
import { base58, base58check, base64, utf8 } from ".";

describe("Coders smoke tests", () => {
/**
* @description For testing base64 coder
* @expected it should encode and decode correctly
*/
test("base64 coder roundtrip", () => {
const decodedBase64 = utf8.decode("this is a base64 encoded string");
const encodedBase64 = "dGhpcyBpcyBhIGJhc2U2NCBlbmNvZGVkIHN0cmluZw==";
Expand All @@ -10,6 +14,10 @@ describe("Coders smoke tests", () => {
expect(base64.decode(encodedBase64)).to.be.deep.equal(decodedBase64);
});

/**
* @description For testing base58 coder
* @expected it should encode and decode correctly
*/
test("base58 coder roundtrip", () => {
const decodedBase58 = utf8.decode("this is a base58 encoded string");
const encodedBase58 = "2mxCXDZDHgWsZCCCUBhmanjEeEFPM5dg8FVb659iiJa";
Expand All @@ -18,6 +26,10 @@ describe("Coders smoke tests", () => {
expect(base58.decode(encodedBase58)).to.be.deep.equal(decodedBase58);
});

/**
* @description For testing base58check coder
* @expected it should encode and decode correctly
*/
test("base58check coder roundtrip", () => {
const decodedBase58check = utf8.decode("this is a base58check encoded string");
const encodedBase58check = "6nURSRrD1s933Ruwq4Gi9XzULMhuRQbX1mYrnY2jknX9pW67uKbADDk";
Expand Down
12 changes: 12 additions & 0 deletions packages/crypto/src/coders/utf8.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,31 @@ import { describe, expect, it, test } from "vitest";
import { utf8 } from "./utf8";

describe("UTF-8 <> bytes serialization", () => {
/**
* @description For testing UTF-8 coder
* @expected it should encode and decode correctly
*/
it("Should roundtrip", () => {
expect(utf8.encode(utf8.decode("this is a regular string"))).to.be.equal(
"this is a regular string"
);
});

/**
* @description For testing UTF-8 coder
* @expected it should encode and decode correctly
*/
test("utf8 to bytes with invalid inputs", () => {
const notAString = true as unknown as string;
expect(() => utf8.decode(notAString)).to.throw(
"Expected an object of type 'string', got 'boolean'."
);
});

/**
* @description For testing UTF-8 coder
* @expected it should encode and decode correctly
*/
test("bytes to utf8 with invalid inputs", () => {
const invalidBytes = {} as unknown as Uint8Array;
expect(() => utf8.encode(invalidBytes)).to.throw(
Expand Down
9 changes: 9 additions & 0 deletions packages/crypto/src/coders/utf8.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
import { assertInstanceOf, assertTypeOf } from "@fleet-sdk/common";
import { BytesCoder } from "../types";

/**
* Converts bytes to utf8 string
* @param bytes
*/
function bytesToUtf8(bytes: Uint8Array): string {
assertInstanceOf(bytes, Uint8Array);

return new TextDecoder().decode(bytes);
}

/**
* Converts utf8 string to bytes
* @param str
* @returns
*/
function utf8ToBytes(str: string): Uint8Array {
assertTypeOf(str, "string");

Expand Down
12 changes: 12 additions & 0 deletions packages/crypto/src/hashes.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,20 @@ import { hex, utf8 } from "./coders";
import { blake2b256, sha256 } from "./hashes";

describe("Hashes smoke tests", () => {
/**
* @description For testing BLAKE2b256 Hash
* @expected it should hash to a correct value
*/
it("Should hash message using BLAKE2b256", () => {
expect(blake2b256(utf8.decode("blake2b256"))).to.be.deep.equal(
hex.decode("eb95e6932cedac15db722fcdb0cfd21437f94690339a716251fad2f89842ea8b")
);
});

/**
* @description For testing SHA256 Hash, regardless of input format
* @expected it should hash to a correct value
*/
it("Should have the same result regardless input format", () => {
const byte = Uint8Array.from([0xde, 0xad, 0xbe, 0xef]);
const hex = "deadbeef";
Expand All @@ -17,6 +25,10 @@ describe("Hashes smoke tests", () => {
expect(sha256(byte)).to.be.deep.equal(sha256(hex));
});

/**
* @description For testing SHA256 Hash
* @expected it should hash to a correct value
*/
it("Should hash message using sha256", () => {
expect(sha256(utf8.decode("sha256"))).to.be.deep.equal(
hex.decode("5d5b09f6dcb2d53a5fffc60c4ac0d55fabdf556069d6631545f42aa6e3500f2e")
Expand Down
12 changes: 12 additions & 0 deletions packages/crypto/src/hashes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,28 @@ import { sha256 as _sha256 } from "@noble/hashes/sha256";
import { hex } from "./coders";
import { BytesInput } from "./types";

/**
* Ensure that the input is a Uint8Array, if not convert it to one
* @param input
*/
function ensureBytes(input: BytesInput): Uint8Array {
if (input instanceof Uint8Array) return input;

return hex.decode(input);
}

/**
* Get the blake2b-256 hash of the input
* @param message
*/
export function blake2b256(message: BytesInput): Uint8Array {
return blake2b(ensureBytes(message), { dkLen: 32 });
}

/**
* Get the sha256 hash of the input
* @param message
*/
export function sha256(message: BytesInput): Uint8Array {
return _sha256(ensureBytes(message));
}