Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: encryption with signatures #494

Merged
merged 10 commits into from
Nov 13, 2023
Merged
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
33 changes: 33 additions & 0 deletions src/lib/adapters/waku/codec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import {
createEncoder as createWakuSymmetricEncoder,
createDecoder as createWakuSymmetricDecoder,
} from '@waku/message-encryption/symmetric'
import { getTopic, type ContentTopic } from './waku'
import { bytesToHex, hexToBytes } from '@waku/utils/bytes'
import { type Hex, fixHex } from './crypto'

function toHex(value: Uint8Array | Hex): Hex {
return typeof value === 'string' ? fixHex(value) : bytesToHex(value)
}

export function createSymmetricEncoder(options: {
contentTopic: ContentTopic
symKey: Uint8Array | Hex
sigPrivKey?: Uint8Array | Hex
}) {
const contentTopic = getTopic(options.contentTopic, toHex(options.symKey))
return createWakuSymmetricEncoder({
...options,
contentTopic,
symKey: hexToBytes(options.symKey),
sigPrivKey: options.sigPrivKey ? hexToBytes(options.sigPrivKey) : undefined,
})
}

export function createSymmetricDecoder(options: {
contentTopic: ContentTopic
symKey: Uint8Array | Hex
}) {
const contentTopic = getTopic(options.contentTopic, toHex(options.symKey))
return createWakuSymmetricDecoder(contentTopic, hexToBytes(options.symKey))
}
19 changes: 3 additions & 16 deletions src/lib/adapters/waku/crypto.test.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { describe, it, expect } from 'vitest'
import { hash, publicKeyToAddress, sign, signatureToPublicKey } from './crypto'
import { publicKeyToAddress } from './crypto'

const testPrivateKey = 'd195918969e09d9394c768e25b621eafc4c360117a9e1eebb0a68bfd53119ba4'
// const testPrivateKey = 'd195918969e09d9394c768e25b621eafc4c360117a9e1eebb0a68bfd53119ba4'
const testCompressedPublicKey = '0374a6b1cea74a7a755396d8c62a3be4eb9098c7bb286dcdfc02ab93e7683c93f9'
const testUncompressedPublicKey =
'0474a6b1cea74a7a755396d8c62a3be4eb9098c7bb286dcdfc02ab93e7683c93f99515f1cf8980e0cb25b6078113813d90d99303aaea1aa34c12805f8355768e21'
const testAddress = publicKeyToAddress(testUncompressedPublicKey)
const testAddress = '0x5018604b6fcfb992e48c102dcff8f9084a68b751'

describe('publicKeyToAddress', () => {
it('calculates correct address for compressed public key', () => {
Expand All @@ -18,16 +18,3 @@ describe('publicKeyToAddress', () => {
expect(address).toEqual(testAddress)
})
})

describe('sign', () => {
it('calculates signature', () => {
const message = 'hello'

const data = new TextEncoder().encode(message)
const signature = sign(testPrivateKey, data)
const messageHash = hash(data)
const recoveredPublicKey = signatureToPublicKey(signature, messageHash)

expect(recoveredPublicKey).toEqual(testCompressedPublicKey)
})
})
23 changes: 6 additions & 17 deletions src/lib/adapters/waku/crypto.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,12 @@
import {
getSharedSecret as nobleGetSharedSecret,
sign as nobleSign,
ProjectivePoint,
Signature,
} from '@noble/secp256k1'
import { getSharedSecret as nobleGetSharedSecret, ProjectivePoint } from '@noble/secp256k1'
import { keccak_256 } from '@noble/hashes/sha3'
import { bytesToHex, hexToBytes } from '@waku/utils/bytes'
import { gcm } from '@noble/ciphers/aes'
import { randomBytes } from '@noble/ciphers/webcrypto/utils'

type Hex = string
export type Hex = string

function fixHex(h: Hex): Hex {
export function fixHex(h: Hex): Hex {
if (h.startsWith('0x')) {
return h.slice(2)
}
Expand Down Expand Up @@ -53,13 +48,7 @@ export function publicKeyToAddress(publicKey: Hex): Hex {
return '0x' + keyHash.slice(-40)
}

export function signatureToPublicKey(signature: Hex, messageHash: Hex): Hex {
const publicKey = Signature.fromCompact(fixHex(signature)).recoverPublicKey(fixHex(messageHash))
return publicKey.toHex(true)
}

export function sign(privateKey: Hex, data: Uint8Array): Hex {
const messageHash = hash(data)
const signature = nobleSign(messageHash, fixHex(privateKey))
return signature.toCompactHex()
export function compressPublicKey(publicKey: Hex | Uint8Array): Hex {
publicKey = typeof publicKey === 'string' ? fixHex(publicKey) : bytesToHex(publicKey)
return ProjectivePoint.fromHex(publicKey).toHex(true)
}
Loading