From c31e7d07149989a696b06d5a3c6c42274f0bacc5 Mon Sep 17 00:00:00 2001 From: Igor Shadurin Date: Mon, 13 Mar 2023 13:32:29 +0300 Subject: [PATCH 1/2] fix: bmtHashString replaced with keccak256Hash --- src/account/utils.ts | 16 ++----- src/chunk/bmt.ts | 3 +- src/feed/api.ts | 9 ++-- src/feed/handler.ts | 4 +- src/utils/encryption.ts | 12 ++++++ test/unit/handler.spec.ts | 87 ++++++++++++++++++++------------------- 6 files changed, 67 insertions(+), 64 deletions(-) diff --git a/src/account/utils.ts b/src/account/utils.ts index f7061579..329c7a54 100644 --- a/src/account/utils.ts +++ b/src/account/utils.ts @@ -1,11 +1,12 @@ import { Data, Utils } from '@ethersphere/bee-js' import { bmtHash } from '../chunk/bmt' -import { makeSpan, stringToBytes, wrapBytesWithHelpers } from '../utils/bytes' +import { makeSpan, wrapBytesWithHelpers } from '../utils/bytes' import { AccountData } from './account-data' import { isValidMnemonic } from 'ethers/lib/utils' import CryptoJS from 'crypto-js' import { replaceAll } from '../utils/string' import { assertString } from '../utils/type' +import { keccak256Hash } from '../utils/encryption' export const MNEMONIC_LENGTH = 12 export const MAX_CHUNK_LENGTH = 4096 @@ -59,17 +60,6 @@ export function extractChunkContent(data: Data): Data { return wrapBytesWithHelpers(data.slice(chunkContentPosition)) } -/** - * Calculate a Binary Merkle Tree hash for a string - * - * @returns the keccak256 hash in a byte array - */ -export function bmtHashString(stringData: string): Utils.Bytes<32> { - const payload = stringToBytes(stringData) - - return bmtHashBytes(payload) -} - /** * Calculate a Binary Merkle Tree hash for a bytes array * @@ -183,7 +173,7 @@ export function removeZeroFromHex(value: string): string { export function createCredentialsTopic(username: string, password: string): Utils.Bytes<32> { const topic = AUTH_VERSION + username + password - return bmtHashString(topic) + return keccak256Hash(topic) } /** diff --git a/src/chunk/bmt.ts b/src/chunk/bmt.ts index b0209153..bf5014c8 100644 --- a/src/chunk/bmt.ts +++ b/src/chunk/bmt.ts @@ -1,6 +1,7 @@ import { keccak256 } from 'js-sha3' import { BeeArgumentError } from '../utils/error' import { Utils } from '@ethersphere/bee-js' +import { keccak256Hash } from '../utils/encryption' const MAX_CHUNK_PAYLOAD_SIZE = 4096 const SEGMENT_SIZE = 32 @@ -27,7 +28,7 @@ export function bmtHash(chunkContent: Uint8Array): Utils.Bytes<32> { const rootHash = bmtRootHash(payload) const chunkHashInput = new Uint8Array([...span, ...rootHash]) - return Utils.keccak256Hash(chunkHashInput) + return keccak256Hash(chunkHashInput) } function bmtRootHash(payload: Uint8Array): Uint8Array { diff --git a/src/feed/api.ts b/src/feed/api.ts index ea113e86..b93c5278 100644 --- a/src/feed/api.ts +++ b/src/feed/api.ts @@ -1,5 +1,4 @@ import { Bee, Data, Reference, RequestOptions, Utils } from '@ethersphere/bee-js' -import { bmtHashString } from '../account/utils' import { getId } from './handler' import { lookup } from './lookup/linear' import { Epoch, HIGHEST_LEVEL } from './lookup/epoch' @@ -7,7 +6,7 @@ import { bytesToHex } from '../utils/hex' import { getUnixTimestamp } from '../utils/time' import { LookupAnswer } from './types' import { Connection } from '../connection/connection' -import { encryptBytes, PodPasswordBytes } from '../utils/encryption' +import { encryptBytes, keccak256Hash, PodPasswordBytes } from '../utils/encryption' import { utils, Wallet } from 'ethers' /** @@ -29,11 +28,11 @@ export async function getFeedData( address: Utils.EthAddress | Uint8Array, requestOptions?: RequestOptions, ): Promise { - const topicHash = bmtHashString(topic) + const topicHash = keccak256Hash(topic) return lookup(0, async (epoch: Epoch, time: number): Promise => { const tempId = getId(topicHash, time, epoch.level) - const chunkReference = bytesToHex(Utils.keccak256Hash(tempId.buffer, address.buffer)) + const chunkReference = bytesToHex(keccak256Hash(tempId.buffer, address.buffer)) return bee.downloadChunk(chunkReference, requestOptions) }) @@ -84,7 +83,7 @@ export async function writeFeedDataRaw( epoch = new Epoch(HIGHEST_LEVEL, getUnixTimestamp()) } - const topicHash = bmtHashString(topic) + const topicHash = keccak256Hash(topic) const id = getId(topicHash, epoch.time, epoch.level) const socWriter = connection.bee.makeSOCWriter(wallet.privateKey) diff --git a/src/feed/handler.ts b/src/feed/handler.ts index ed84fbcb..005eeadf 100644 --- a/src/feed/handler.ts +++ b/src/feed/handler.ts @@ -1,6 +1,6 @@ import { Utils } from '@ethersphere/bee-js' -import { makeContentAddressedChunk } from '../chunk/cac' import { Epoch, HIGHEST_LEVEL } from './lookup/epoch' +import { keccak256Hash } from '../utils/encryption' const TOPIC_LENGTH = 32 @@ -26,5 +26,5 @@ export function getId(topic: Utils.Bytes<32>, time = 0, level = HIGHEST_LEVEL): bufId[cursor + i] = eid[i] } - return makeContentAddressedChunk(bufId).address() + return keccak256Hash(bufId) } diff --git a/src/utils/encryption.ts b/src/utils/encryption.ts index 29587003..7beb0fea 100644 --- a/src/utils/encryption.ts +++ b/src/utils/encryption.ts @@ -5,6 +5,7 @@ import { bytesToHex } from './hex' import { bytesToString, bytesToWordArray, wordArrayToBytes } from './bytes' import { isArrayBufferView, isString } from './type' import { jsonParse } from './json' +import { keccak256, Message } from 'js-sha3' export const IV_LENGTH = 16 export const POD_PASSWORD_LENGTH = 32 @@ -123,3 +124,14 @@ export function decryptJson(password: string | Uint8Array, data: Uint8Array): un return jsonParse(bytesToString(decryptBytes(passwordString, data)), 'decrypted json') } + +/** + * Calculates the keccak256 hash with correct types + */ +export function keccak256Hash(...messages: Message[]): Utils.Bytes<32> { + const hasher = keccak256.create() + + messages.forEach(bytes => hasher.update(bytes)) + + return Uint8Array.from(hasher.digest()) as Utils.Bytes<32> +} diff --git a/test/unit/handler.spec.ts b/test/unit/handler.spec.ts index 284da8a9..69d698ba 100644 --- a/test/unit/handler.spec.ts +++ b/test/unit/handler.spec.ts @@ -99,8 +99,8 @@ describe('handler', () => { time: 0, level: 31, result: [ - 192, 199, 235, 193, 4, 30, 150, 71, 114, 55, 81, 241, 36, 4, 167, 21, 11, 203, 97, 51, 192, 41, 85, 83, 26, - 196, 220, 74, 172, 129, 230, 145, + 137, 19, 193, 4, 187, 223, 87, 230, 131, 174, 71, 54, 179, 192, 170, 137, 115, 200, 208, 8, 48, 130, 231, 58, + 27, 125, 244, 100, 224, 149, 0, 106, ], }, { @@ -111,8 +111,8 @@ describe('handler', () => { time: 0, level: 31, result: [ - 33, 152, 66, 62, 214, 250, 233, 47, 80, 227, 143, 184, 49, 194, 68, 62, 86, 72, 251, 251, 255, 109, 199, 93, - 139, 156, 147, 136, 113, 94, 106, 14, + 96, 40, 10, 151, 168, 195, 183, 128, 50, 255, 205, 132, 115, 176, 20, 201, 179, 95, 199, 161, 154, 75, 149, + 246, 158, 47, 158, 144, 245, 92, 164, 125, ], }, { @@ -123,8 +123,8 @@ describe('handler', () => { time: 0, level: 31, result: [ - 78, 50, 123, 238, 90, 128, 131, 200, 147, 25, 242, 75, 191, 72, 114, 82, 159, 81, 221, 17, 172, 22, 113, 201, - 129, 67, 224, 22, 0, 73, 115, 96, + 232, 154, 186, 138, 160, 29, 85, 104, 241, 2, 110, 46, 106, 24, 253, 196, 147, 65, 143, 93, 88, 178, 30, 200, + 81, 100, 30, 212, 2, 86, 16, 148, ], }, { @@ -135,8 +135,8 @@ describe('handler', () => { time: 0, level: 31, result: [ - 78, 50, 123, 238, 90, 128, 131, 200, 147, 25, 242, 75, 191, 72, 114, 82, 159, 81, 221, 17, 172, 22, 113, 201, - 129, 67, 224, 22, 0, 73, 115, 96, + 232, 154, 186, 138, 160, 29, 85, 104, 241, 2, 110, 46, 106, 24, 253, 196, 147, 65, 143, 93, 88, 178, 30, 200, + 81, 100, 30, 212, 2, 86, 16, 148, ], }, { @@ -147,8 +147,8 @@ describe('handler', () => { time: 0, level: 31, result: [ - 206, 136, 204, 81, 249, 114, 10, 71, 213, 152, 130, 20, 37, 235, 20, 17, 80, 169, 195, 156, 159, 27, 12, 16, - 230, 128, 181, 85, 118, 123, 199, 218, + 224, 229, 31, 229, 74, 157, 228, 135, 101, 165, 181, 236, 240, 16, 28, 251, 67, 151, 183, 77, 61, 190, 173, + 192, 116, 112, 222, 238, 14, 150, 231, 45, ], }, { @@ -159,8 +159,8 @@ describe('handler', () => { time: 0, level: 31, result: [ - 253, 205, 215, 201, 10, 147, 239, 210, 118, 22, 30, 253, 27, 13, 194, 95, 235, 234, 36, 100, 54, 46, 236, 68, - 186, 16, 239, 185, 176, 134, 78, 164, + 29, 196, 17, 153, 124, 114, 151, 22, 166, 28, 67, 214, 195, 74, 176, 2, 128, 150, 20, 239, 115, 127, 95, 213, + 32, 206, 46, 115, 104, 68, 53, 26, ], }, { @@ -171,8 +171,8 @@ describe('handler', () => { time: 0, level: 31, result: [ - 119, 22, 217, 89, 177, 127, 217, 230, 83, 0, 238, 71, 243, 141, 219, 57, 174, 63, 220, 142, 131, 207, 243, - 143, 44, 117, 191, 238, 171, 38, 181, 104, + 105, 227, 231, 100, 44, 42, 103, 134, 253, 119, 46, 159, 50, 218, 232, 189, 84, 64, 4, 196, 36, 58, 40, 82, + 210, 83, 37, 120, 29, 90, 14, 23, ], }, { @@ -183,8 +183,8 @@ describe('handler', () => { time: 0, level: 31, result: [ - 119, 22, 217, 89, 177, 127, 217, 230, 83, 0, 238, 71, 243, 141, 219, 57, 174, 63, 220, 142, 131, 207, 243, - 143, 44, 117, 191, 238, 171, 38, 181, 104, + 105, 227, 231, 100, 44, 42, 103, 134, 253, 119, 46, 159, 50, 218, 232, 189, 84, 64, 4, 196, 36, 58, 40, 82, + 210, 83, 37, 120, 29, 90, 14, 23, ], }, { @@ -195,8 +195,8 @@ describe('handler', () => { time: 0, level: 31, result: [ - 206, 136, 204, 81, 249, 114, 10, 71, 213, 152, 130, 20, 37, 235, 20, 17, 80, 169, 195, 156, 159, 27, 12, 16, - 230, 128, 181, 85, 118, 123, 199, 218, + 224, 229, 31, 229, 74, 157, 228, 135, 101, 165, 181, 236, 240, 16, 28, 251, 67, 151, 183, 77, 61, 190, 173, + 192, 116, 112, 222, 238, 14, 150, 231, 45, ], }, { @@ -207,8 +207,8 @@ describe('handler', () => { time: 0, level: 31, result: [ - 253, 205, 215, 201, 10, 147, 239, 210, 118, 22, 30, 253, 27, 13, 194, 95, 235, 234, 36, 100, 54, 46, 236, 68, - 186, 16, 239, 185, 176, 134, 78, 164, + 29, 196, 17, 153, 124, 114, 151, 22, 166, 28, 67, 214, 195, 74, 176, 2, 128, 150, 20, 239, 115, 127, 95, 213, + 32, 206, 46, 115, 104, 68, 53, 26, ], }, { @@ -219,8 +219,8 @@ describe('handler', () => { time: 0, level: 31, result: [ - 206, 136, 204, 81, 249, 114, 10, 71, 213, 152, 130, 20, 37, 235, 20, 17, 80, 169, 195, 156, 159, 27, 12, 16, - 230, 128, 181, 85, 118, 123, 199, 218, + 224, 229, 31, 229, 74, 157, 228, 135, 101, 165, 181, 236, 240, 16, 28, 251, 67, 151, 183, 77, 61, 190, 173, + 192, 116, 112, 222, 238, 14, 150, 231, 45, ], }, { @@ -231,8 +231,8 @@ describe('handler', () => { time: 1647862022, level: 31, result: [ - 207, 41, 219, 83, 213, 196, 65, 130, 180, 200, 178, 34, 177, 224, 3, 110, 180, 139, 190, 221, 59, 96, 135, - 174, 128, 66, 110, 158, 39, 87, 116, 170, + 226, 61, 113, 161, 213, 84, 251, 42, 70, 128, 28, 110, 124, 221, 125, 52, 241, 59, 79, 83, 231, 163, 171, 145, + 3, 90, 242, 32, 8, 59, 83, 250, ], }, { @@ -243,8 +243,8 @@ describe('handler', () => { time: 0, level: 31, result: [ - 89, 210, 219, 4, 139, 95, 193, 117, 77, 224, 198, 71, 179, 50, 253, 116, 44, 48, 209, 193, 37, 205, 110, 44, - 195, 104, 114, 192, 242, 109, 21, 33, + 43, 225, 162, 162, 82, 69, 80, 236, 180, 162, 109, 230, 25, 127, 64, 179, 24, 87, 207, 63, 157, 95, 51, 175, + 43, 61, 77, 51, 167, 166, 170, 242, ], }, { @@ -255,8 +255,8 @@ describe('handler', () => { time: 1647862034, level: 31, result: [ - 207, 41, 219, 83, 213, 196, 65, 130, 180, 200, 178, 34, 177, 224, 3, 110, 180, 139, 190, 221, 59, 96, 135, - 174, 128, 66, 110, 158, 39, 87, 116, 170, + 226, 61, 113, 161, 213, 84, 251, 42, 70, 128, 28, 110, 124, 221, 125, 52, 241, 59, 79, 83, 231, 163, 171, 145, + 3, 90, 242, 32, 8, 59, 83, 250, ], }, { @@ -267,8 +267,8 @@ describe('handler', () => { time: 1647862034, level: 25, result: [ - 60, 20, 31, 3, 74, 240, 186, 225, 95, 128, 3, 45, 78, 174, 68, 80, 244, 167, 163, 92, 79, 203, 160, 248, 189, - 126, 27, 232, 220, 32, 247, 91, + 191, 233, 150, 32, 204, 164, 167, 185, 150, 21, 29, 120, 78, 56, 133, 11, 11, 114, 125, 27, 11, 112, 142, 93, + 203, 41, 56, 206, 194, 117, 158, 161, ], }, { @@ -279,8 +279,8 @@ describe('handler', () => { time: 1647862034, level: 24, result: [ - 30, 71, 181, 179, 118, 145, 132, 97, 217, 248, 190, 200, 120, 13, 52, 120, 115, 53, 93, 63, 103, 106, 135, - 118, 155, 159, 77, 77, 207, 65, 185, 153, + 159, 94, 207, 0, 185, 61, 37, 206, 170, 1, 158, 43, 20, 243, 185, 38, 40, 130, 233, 206, 35, 3, 229, 195, 192, + 145, 55, 48, 188, 112, 252, 181, ], }, { @@ -291,8 +291,8 @@ describe('handler', () => { time: 1647862034, level: 23, result: [ - 93, 12, 120, 127, 134, 93, 56, 142, 245, 13, 169, 57, 202, 121, 133, 160, 232, 127, 36, 27, 141, 145, 88, 166, - 175, 2, 201, 219, 46, 254, 92, 140, + 246, 157, 148, 197, 225, 67, 186, 35, 17, 2, 185, 128, 240, 110, 242, 10, 134, 55, 50, 16, 160, 229, 128, 152, + 218, 218, 36, 28, 184, 224, 163, 150, ], }, { @@ -303,8 +303,8 @@ describe('handler', () => { time: 1647862034, level: 22, result: [ - 46, 185, 143, 15, 139, 48, 92, 198, 215, 116, 32, 223, 40, 114, 54, 140, 27, 206, 13, 153, 235, 201, 118, 163, - 241, 208, 48, 91, 127, 95, 142, 153, + 193, 236, 34, 45, 89, 227, 46, 168, 161, 107, 87, 54, 118, 118, 177, 57, 239, 159, 46, 92, 39, 193, 127, 45, + 105, 40, 175, 49, 42, 181, 135, 186, ], }, { @@ -315,8 +315,8 @@ describe('handler', () => { time: 1647862034, level: 21, result: [ - 246, 20, 183, 223, 195, 172, 31, 24, 1, 194, 140, 87, 192, 225, 16, 12, 198, 109, 252, 126, 144, 14, 176, 210, - 11, 49, 4, 53, 40, 32, 11, 181, + 59, 242, 121, 83, 124, 83, 249, 32, 67, 214, 142, 30, 140, 147, 109, 90, 86, 210, 178, 110, 240, 110, 148, + 136, 180, 45, 124, 90, 124, 112, 114, 61, ], }, { @@ -327,8 +327,8 @@ describe('handler', () => { time: 1647862034, level: 20, result: [ - 124, 116, 161, 57, 208, 190, 137, 48, 82, 15, 159, 154, 235, 252, 20, 82, 67, 193, 253, 158, 31, 79, 50, 182, - 150, 117, 115, 148, 179, 160, 252, 120, + 69, 233, 198, 244, 94, 12, 108, 53, 125, 82, 215, 223, 200, 203, 204, 205, 225, 79, 37, 237, 91, 232, 227, + 117, 64, 72, 15, 94, 150, 214, 237, 136, ], }, { @@ -339,15 +339,16 @@ describe('handler', () => { time: 1647312895, level: 20, result: [ - 230, 88, 42, 172, 164, 128, 33, 134, 252, 63, 0, 166, 90, 24, 246, 133, 197, 5, 132, 67, 175, 255, 209, 196, - 116, 48, 164, 206, 174, 222, 233, 123, + 142, 93, 254, 156, 169, 52, 41, 244, 1, 178, 180, 2, 22, 140, 205, 145, 51, 115, 170, 178, 80, 74, 213, 233, + 217, 121, 212, 97, 116, 226, 204, 159, ], }, ] for (const example of examples) { const result = getId(numbersToSegment(example.topic), example.time, example.level) expect(result.length).toEqual(32) - expect(result.toString().split(',').map(Number)).toEqual(example.result) + const calculatedResult = result.toString().split(',').map(Number) + expect(calculatedResult).toEqual(example.result) } }) }) From 9c9d6a3ea5a279547a9390b8326005a9332d65a5 Mon Sep 17 00:00:00 2001 From: Igor Shadurin Date: Wed, 15 Mar 2023 16:28:54 +0300 Subject: [PATCH 2/2] refactor: changed POD_TOPIC --- src/pod/personal-storage.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pod/personal-storage.ts b/src/pod/personal-storage.ts index 11e9fad8..88975203 100644 --- a/src/pod/personal-storage.ts +++ b/src/pod/personal-storage.ts @@ -26,7 +26,7 @@ import { getCacheKey, setEpochCache } from '../cache/utils' import { getPodsList } from './cache/api' import { getNextEpoch } from '../feed/lookup/utils' -export const POD_TOPIC = 'Pods' +export const POD_TOPIC = 'PODs' export class PersonalStorage { constructor(private accountData: AccountData) {}