Skip to content

Commit

Permalink
feat: implement deterministic v2 conversation topics
Browse files Browse the repository at this point in the history
  • Loading branch information
nakajima authored and rygine committed May 23, 2023
1 parent 50e166d commit c3f2d13
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 6 deletions.
2 changes: 1 addition & 1 deletion src/crypto/ecies.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ function getAes(
const aesCbcEncrypt = getAes('encrypt')
const aesCbcDecrypt = getAes('decrypt')

async function hmacSha256Sign(key: Buffer, msg: Buffer) {
export async function hmacSha256Sign(key: Buffer, msg: Buffer) {
const newKey = await subtle.importKey(
'raw',
key,
Expand Down
8 changes: 6 additions & 2 deletions src/crypto/encryption.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,15 +71,19 @@ function aesGcmParams(

// Derive AES-256-GCM key from a shared secret and salt.
// Returns crypto.CryptoKey suitable for the encrypt/decrypt API
async function hkdf(secret: Uint8Array, salt: Uint8Array): Promise<CryptoKey> {
export async function hkdf(
secret: Uint8Array,
salt: Uint8Array,
extractable = false
): Promise<CryptoKey> {
const key = await crypto.subtle.importKey('raw', secret, 'HKDF', false, [
'deriveKey',
])
return crypto.subtle.deriveKey(
{ name: 'HKDF', hash: 'SHA-256', salt, info: hkdfNoInfo },
key,
{ name: 'AES-GCM', length: 256 },
false,
extractable,
['encrypt', 'decrypt']
)
}
42 changes: 40 additions & 2 deletions src/keystore/InMemoryKeystore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,14 @@ import {
getKeyMaterial,
topicDataToConversationReference,
} from './utils'
import { nsToDate } from '../utils'
import { nsToDate, buildDirectMessageTopicV2 } from '../utils'
import InviteStore from './InviteStore'
import { Persistence } from './persistence'
import LocalAuthenticator from '../authn/LocalAuthenticator'
import { sha256 } from 'ethers/lib/utils'
import { hmacSha256Sign } from '../crypto/ecies'
import { KDFSaltSize } from '../crypto/Ciphertext'
import { hkdf, crypto } from '../crypto/encryption'
const { ErrorCode } = keystore

export default class InMemoryKeystore implements Keystore {
Expand Down Expand Up @@ -248,9 +252,43 @@ export default class InMemoryKeystore implements Keystore {
'missing recipient'
)
}
const invitation = InvitationV1.createRandom(req.context)
// const invitation = InvitationV1.createRandom(req.context)
const created = nsToDate(req.createdNs)
const recipient = toSignedPublicKeyBundle(req.recipient)

const secret = await this.v2Keys.sharedSecret(
recipient,
this.v2Keys.getCurrentPreKey().publicKey,
false
)

const msg = new TextEncoder().encode(
JSON.stringify({
conversationId: req.context?.conversationId || '',
participants: [
this.accountAddress,
await recipient.walletSignatureAddress(),
].sort(),
})
)

const topic = sha256(
await hmacSha256Sign(Buffer.from(secret), Buffer.from(msg))
)

const salt = getRandomValues(new Uint8Array(KDFSaltSize))
const derivedKey = await hkdf(secret, salt, true)

const keyMaterial = new Uint8Array(
await crypto.subtle.exportKey('raw', derivedKey)
)

const invitation = new InvitationV1({
topic: buildDirectMessageTopicV2(topic),
aes256GcmHkdfSha256: { keyMaterial },
context: req.context,
})

const sealed = await SealedInvitation.createV1({
sender: this.v2Keys,
recipient,
Expand Down
8 changes: 7 additions & 1 deletion test/keystore/InMemoryKeystore.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -457,7 +457,13 @@ describe('InMemoryKeystore', () => {
const shuffled = [...timestamps].sort(() => Math.random() - 0.5)

await Promise.all(
shuffled.map((createdAt) => {
shuffled.map(async (createdAt) => {
let keys = await PrivateKeyBundleV1.generate(newWallet())

const recipient = SignedPublicKeyBundle.fromLegacyBundle(
keys.getPublicKeyBundle()
)

return aliceKeystore.createInvite({
recipient,
createdNs: dateToNs(createdAt),
Expand Down

0 comments on commit c3f2d13

Please sign in to comment.