Skip to content

Commit

Permalink
feat: refactor the codebase
Browse files Browse the repository at this point in the history
  • Loading branch information
wemeetagain committed Dec 16, 2023
1 parent 823404c commit 54f7e32
Show file tree
Hide file tree
Showing 20 changed files with 897 additions and 1,201 deletions.
22 changes: 17 additions & 5 deletions src/crypto.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,27 @@
import { type Uint8ArrayList } from 'uint8arraylist'
import type { bytes32, Hkdf, KeyPair } from './types.js'
import type { ICrypto, KeyPair } from './types.js'
import type { Uint8ArrayList } from 'uint8arraylist'

/** Underlying crypto implementation, meant to be overridable */
export interface ICryptoInterface {
hashSHA256(data: Uint8Array | Uint8ArrayList): Uint8Array

getHKDF(ck: bytes32, ikm: Uint8Array): Hkdf
getHKDF(ck: Uint8Array, ikm: Uint8Array): [Uint8Array, Uint8Array, Uint8Array]

generateX25519KeyPair(): KeyPair
generateX25519KeyPairFromSeed(seed: Uint8Array): KeyPair
generateX25519SharedKey(privateKey: Uint8Array | Uint8ArrayList, publicKey: Uint8Array | Uint8ArrayList): Uint8Array

chaCha20Poly1305Encrypt(plaintext: Uint8Array | Uint8ArrayList, nonce: Uint8Array, ad: Uint8Array, k: bytes32): Uint8ArrayList | Uint8Array
chaCha20Poly1305Decrypt(ciphertext: Uint8Array | Uint8ArrayList, nonce: Uint8Array, ad: Uint8Array, k: bytes32, dst?: Uint8Array): Uint8ArrayList | Uint8Array | null
chaCha20Poly1305Encrypt(plaintext: Uint8Array | Uint8ArrayList, nonce: Uint8Array, ad: Uint8Array, k: Uint8Array): Uint8ArrayList | Uint8Array
chaCha20Poly1305Decrypt(ciphertext: Uint8Array | Uint8ArrayList, nonce: Uint8Array, ad: Uint8Array, k: Uint8Array, dst?: Uint8Array): Uint8ArrayList | Uint8Array
}

export function wrapCrypto (crypto: ICryptoInterface): ICrypto {
return {
generateKeypair: crypto.generateX25519KeyPair,
dh: (keypair, publicKey) => crypto.generateX25519SharedKey(keypair.privateKey, publicKey).subarray(0, 32),
encrypt: crypto.chaCha20Poly1305Encrypt,
decrypt: crypto.chaCha20Poly1305Decrypt,
hash: crypto.hashSHA256,
hkdf: crypto.getHKDF
}
}
6 changes: 5 additions & 1 deletion src/crypto/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,11 @@ const asCrypto: Pick<ICryptoInterface, 'hashSHA256' | 'chaCha20Poly1305Encrypt'
return asImpl.seal(k, nonce, plaintext.subarray(), ad)
},
chaCha20Poly1305Decrypt (ciphertext, nonce, ad, k, dst) {
return asImpl.open(k, nonce, ciphertext.subarray(), ad, dst)
const plaintext = asImpl.open(k, nonce, ciphertext.subarray(), ad, dst)
if (!plaintext) {
throw new Error('Invalid chacha20poly1305 decryption')
}
return plaintext
}
}

Expand Down
8 changes: 4 additions & 4 deletions src/crypto/js.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@ import { x25519 } from '@noble/curves/ed25519'
import { extract, expand } from '@noble/hashes/hkdf'
import { sha256 } from '@noble/hashes/sha256'
import type { ICryptoInterface } from '../crypto.js'
import type { bytes32, Hkdf, KeyPair } from '../types.js'
import type { KeyPair } from '../types.js'
import type { Uint8ArrayList } from 'uint8arraylist'

export const pureJsCrypto: ICryptoInterface = {
hashSHA256 (data: Uint8Array | Uint8ArrayList): Uint8Array {
return sha256(data.subarray())
},

getHKDF (ck: bytes32, ikm: Uint8Array): Hkdf {
getHKDF (ck: Uint8Array, ikm: Uint8Array): [Uint8Array, Uint8Array, Uint8Array] {
const prk = extract(sha256, ikm, ck)
const okmU8Array = expand(sha256, prk, undefined, 96)
const okm = okmU8Array
Expand Down Expand Up @@ -46,11 +46,11 @@ export const pureJsCrypto: ICryptoInterface = {
return x25519.getSharedSecret(privateKey.subarray(), publicKey.subarray())
},

chaCha20Poly1305Encrypt (plaintext: Uint8Array | Uint8ArrayList, nonce: Uint8Array, ad: Uint8Array, k: bytes32): Uint8Array {
chaCha20Poly1305Encrypt (plaintext: Uint8Array | Uint8ArrayList, nonce: Uint8Array, ad: Uint8Array, k: Uint8Array): Uint8Array {
return chacha20poly1305(k, nonce, ad).encrypt(plaintext.subarray())
},

chaCha20Poly1305Decrypt (ciphertext: Uint8Array | Uint8ArrayList, nonce: Uint8Array, ad: Uint8Array, k: bytes32, dst?: Uint8Array): Uint8Array | null {
chaCha20Poly1305Decrypt (ciphertext: Uint8Array | Uint8ArrayList, nonce: Uint8Array, ad: Uint8Array, k: Uint8Array, dst?: Uint8Array): Uint8Array {
return chacha20poly1305(k, nonce, ad).decrypt(ciphertext.subarray(), dst)
}
}
53 changes: 2 additions & 51 deletions src/encoder.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { Uint8ArrayList } from 'uint8arraylist'
import { alloc as uint8ArrayAlloc, allocUnsafe as uint8ArrayAllocUnsafe } from 'uint8arrays/alloc'
import type { bytes, MessageBuffer } from './types.js'
import { type Uint8ArrayList } from 'uint8arraylist'
import { allocUnsafe as uint8ArrayAllocUnsafe } from 'uint8arrays/alloc'
import type { LengthDecoderFunction } from 'it-length-prefixed'

export const uint16BEEncode = (value: number): Uint8Array => {
Expand All @@ -24,51 +23,3 @@ export const uint16BEDecode: LengthDecoderFunction = (data: Uint8Array | Uint8Ar
return data.getUint16(0)
}
uint16BEDecode.bytes = 2

export function encode0 (message: MessageBuffer): Uint8ArrayList {
return new Uint8ArrayList(message.ne, message.ciphertext)
}

export function encode1 (message: MessageBuffer): Uint8ArrayList {
return new Uint8ArrayList(message.ne, message.ns, message.ciphertext)
}

export function encode2 (message: MessageBuffer): Uint8ArrayList {
return new Uint8ArrayList(message.ns, message.ciphertext)
}

export function decode0 (input: bytes): MessageBuffer {
if (input.length < 32) {
throw new Error('Cannot decode stage 0 MessageBuffer: length less than 32 bytes.')
}

return {
ne: input.subarray(0, 32),
ciphertext: input.subarray(32, input.length),
ns: uint8ArrayAlloc(0)
}
}

export function decode1 (input: bytes): MessageBuffer {
if (input.length < 80) {
throw new Error('Cannot decode stage 1 MessageBuffer: length less than 80 bytes.')
}

return {
ne: input.subarray(0, 32),
ns: input.subarray(32, 80),
ciphertext: input.subarray(80, input.length)
}
}

export function decode2 (input: bytes): MessageBuffer {
if (input.length < 48) {
throw new Error('Cannot decode stage 2 MessageBuffer: length less than 48 bytes.')
}

return {
ne: uint8ArrayAlloc(0),
ns: input.subarray(0, 48),
ciphertext: input.subarray(48, input.length)
}
}
179 changes: 0 additions & 179 deletions src/handshake-xx.ts

This file was deleted.

Loading

0 comments on commit 54f7e32

Please sign in to comment.