Skip to content

Commit

Permalink
fix: debug mode hash wrong for version -39 or lower
Browse files Browse the repository at this point in the history
  • Loading branch information
Jack-Works committed Oct 11, 2019
1 parent e4ee7c6 commit 3ad9e4e
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 26 deletions.
2 changes: 1 addition & 1 deletion src/components/DebugModeUI/PostHashDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ export function DebugModeUI_PostHashDialog(props: { post: string; network: strin
useAsync(() => {
if (!payload) return Promise.resolve([] as typeof hashMap)
const ivID = new PostIVIdentifier(props.network, payload.iv)
return Services.Crypto.debugShowAllPossibleHashForPost(ivID)
return Services.Crypto.debugShowAllPossibleHashForPost(ivID, payload.version)
}, [props.post]).then(setHashMap)
return (
<>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { PostIVIdentifier } from '../../../database/type'
import { queryPeopleDB } from '../../../database/people'
import { hashPostSalt, hashCryptoKey } from '../../../network/gun/version.2/hash'
import { hashPostSalt, hashCryptoKey, hashCryptoKeyUnstable } from '../../../network/gun/version.2/hash'

export async function debugShowAllPossibleHashForPost(post: PostIVIdentifier) {
export async function debugShowAllPossibleHashForPost(post: PostIVIdentifier, payloadVersion: -38 | -39 | -40) {
const friends = await queryPeopleDB(x => x.network === post.network)
return Promise.all(
friends
Expand All @@ -11,7 +11,9 @@ export async function debugShowAllPossibleHashForPost(post: PostIVIdentifier) {
async x =>
[
x.identifier.toText(),
(await hashPostSalt(post.postIV)) + '-' + (await hashCryptoKey(x.publicKey!, true)),
(await hashPostSalt(post.postIV)) +
'-' +
(await (payloadVersion >= -38 ? hashCryptoKey : hashCryptoKeyUnstable)(x.publicKey!)),
] as [string, string],
),
)
Expand Down
36 changes: 20 additions & 16 deletions src/network/gun/version.2/hash.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,26 +22,30 @@ export const hashPostSalt = memoizePromise(async function(postSalt: string) {

const hash = (await Gun.SEA.work(postSalt, hashPair))!
return hash.substring(0, N)
})
}, undefined)

/**
* @param key - The key need to be hashed
* @param stableHash - Set this to true if you're writing new code.
* Unstable hash may cause problem but we cannot just switch to stable hash
* because it may breaks current data.
* @deprecated
*/
export const hashCryptoKey = memoizePromise(async function(key: CryptoKey, stableHash: boolean) {
export const hashCryptoKeyUnstable = memoizePromise(async function(key: CryptoKey) {
const hashPair = `10198a2f-205f-45a6-9987-3488c80113d0`
const N = 2

if (stableHash === true) {
const jwk = await CryptoKeyToJsonWebKey(key)
if (!jwk.x || !jwk.y) throw new Error('Invalid key')
const hash = (await Gun.SEA.work(jwk.x! + jwk.y!, hashPair))!
return hash.substring(0, N)
} else {
const jwk = JSON.stringify(await CryptoKeyToJsonWebKey(key))
const hash = (await Gun.SEA.work(jwk, hashPair))!
return hash.substring(0, N)
}
})
const jwk = JSON.stringify(await CryptoKeyToJsonWebKey(key))
const hash = (await Gun.SEA.work(jwk, hashPair))!
return hash.substring(0, N)
}, undefined)

/**
* @param key - The key need to be hashed
*/
export const hashCryptoKey = memoizePromise(async function(key: CryptoKey) {
const hashPair = `10198a2f-205f-45a6-9987-3488c80113d0`
const N = 2

const jwk = await CryptoKeyToJsonWebKey(key)
if (!jwk.x || !jwk.y) throw new Error('Invalid key')
const hash = (await Gun.SEA.work(jwk.x! + jwk.y!, hashPair))!
return hash.substring(0, N)
}, undefined)
8 changes: 4 additions & 4 deletions src/network/gun/version.2/post.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { OnlyRunInContext } from '@holoflows/kit/es'
import { gun2, SharedAESKeyGun2 } from '.'
import { hashPostSalt, hashCryptoKey } from './hash'
import { hashPostSalt, hashCryptoKey, hashCryptoKeyUnstable } from './hash'
import { PublishedAESKeyRecordV39OrV38 } from '../../../crypto/crypto-alpha-38'

OnlyRunInContext('background', 'gun')
Expand All @@ -18,7 +18,7 @@ export async function queryPostKeysOnGun2(
): Promise<{ keys: SharedAESKeyGun2[]; postHash: string; keyHash: string }> {
const postHash = await hashPostSalt(postSalt)
// In version > -39, we will use stable hash to prevent unstable result for key hashing
const keyHash = await hashCryptoKey(partitionByCryptoKey, version > -39)
const keyHash = await (version > -39 ? hashCryptoKeyUnstable : hashCryptoKey)(partitionByCryptoKey)

// ? here we get the internal node names of gun2[postHash][keyHash]
// ? where gun2[postHash][keyHash] is a list
Expand Down Expand Up @@ -52,7 +52,7 @@ export function subscribePostKeysOnGun2(
) {
hashPostSalt(postSalt).then(postHash => {
// In version > -39, we will use stable hash to prevent unstable result for key hashing
hashCryptoKey(partitionByCryptoKey, version > -39).then(keyHash => {
;(version > -39 ? hashCryptoKeyUnstable : hashCryptoKey)(partitionByCryptoKey).then(keyHash => {
gun2.get(postHash)
// @ts-ignore
.get(keyHash)
Expand Down Expand Up @@ -81,7 +81,7 @@ export async function publishPostAESKeyOnGun2(
const postHash = await hashPostSalt(postSalt)
// Store AES key to gun
receiversKeys.forEach(async ({ aesKey, receiverKey }) => {
const keyHash = await hashCryptoKey(receiverKey, version > -39)
const keyHash = await (version > -39 ? hashCryptoKeyUnstable : hashCryptoKey)(receiverKey)
console.log(`gun[${postHash}][${keyHash}].push(`, aesKey, `)`)
gun2.get(postHash)
// @ts-ignore
Expand Down
12 changes: 10 additions & 2 deletions src/utils/memoize.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,23 @@
import { memoize } from 'lodash-es'
/**
* The promise version of lodash-es/memoize
* @param f An async function
* @param resolver If the function has 1 param, it can be undefined
* as `x => x`. If it has more than 1 param, you must specify a function
* to map the param the memoize key.
*/
export function memoizePromise<T extends (...args: Args) => PromiseLike<any>, Args extends any[]>(
f: T,
resolver: (...args: Args) => any = ((a: any) => a) as any,
resolver: Args[1] extends undefined ? undefined | ((...args: Args) => unknown) : (...args: Args) => unknown,
) {
if (resolver === undefined) resolver = ((x: any) => x) as any
const memorizedFunction = memoize(
(async function(...args: Args) {
try {
// ? DO NOT remove "await" here
return await f(...args)
} catch (e) {
memorizedFunction.cache.delete(resolver(...args))
memorizedFunction.cache.delete(resolver!(...args))
throw e
}
} as any) as T,
Expand Down

0 comments on commit 3ad9e4e

Please sign in to comment.