|
1 | 1 | import crypto from 'node:crypto' |
2 | 2 | import { newInstance, ChaCha20Poly1305 } from '@chainsafe/as-chacha20poly1305' |
3 | 3 | import { digest } from '@chainsafe/as-sha256' |
| 4 | +import { concat as uint8ArrayConcat } from 'uint8arrays/concat' |
4 | 5 | import { isElectronMain } from 'wherearewe' |
5 | 6 | import { pureJsCrypto } from './js.js' |
| 7 | +import type { KeyPair } from '../@types/libp2p.js' |
6 | 8 | import type { ICryptoInterface } from '../crypto.js' |
7 | 9 |
|
8 | 10 | const ctx = newInstance() |
9 | 11 | const asImpl = new ChaCha20Poly1305(ctx) |
10 | 12 | const CHACHA_POLY1305 = 'chacha20-poly1305' |
| 13 | +const PKCS8_PREFIX = Buffer.from([0x30, 0x2e, 0x02, 0x01, 0x00, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65, 0x6e, 0x04, 0x22, 0x04, 0x20]) |
| 14 | +const X25519_PREFIX = Buffer.from([0x30, 0x2a, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65, 0x6e, 0x03, 0x21, 0x00]) |
11 | 15 | const nodeCrypto: Pick<ICryptoInterface, 'hashSHA256' | 'chaCha20Poly1305Encrypt' | 'chaCha20Poly1305Decrypt'> = { |
12 | 16 | hashSHA256 (data) { |
13 | 17 | return crypto.createHash('sha256').update(data).digest() |
@@ -76,6 +80,68 @@ export const defaultCrypto: ICryptoInterface = { |
76 | 80 | return asCrypto.chaCha20Poly1305Decrypt(ciphertext, nonce, ad, k, dst) |
77 | 81 | } |
78 | 82 | return nodeCrypto.chaCha20Poly1305Decrypt(ciphertext, nonce, ad, k, dst) |
| 83 | + }, |
| 84 | + generateX25519KeyPair (): KeyPair { |
| 85 | + const { publicKey, privateKey } = crypto.generateKeyPairSync('x25519', { |
| 86 | + publicKeyEncoding: { |
| 87 | + type: 'spki', |
| 88 | + format: 'der' |
| 89 | + }, |
| 90 | + privateKeyEncoding: { |
| 91 | + type: 'pkcs8', |
| 92 | + format: 'der' |
| 93 | + } |
| 94 | + }) |
| 95 | + |
| 96 | + return { |
| 97 | + publicKey: publicKey.subarray(12), |
| 98 | + privateKey: privateKey.subarray(16) |
| 99 | + } |
| 100 | + }, |
| 101 | + generateX25519KeyPairFromSeed (seed: Uint8Array): KeyPair { |
| 102 | + const privateKey = crypto.createPrivateKey({ |
| 103 | + key: Buffer.concat([ |
| 104 | + PKCS8_PREFIX, |
| 105 | + seed |
| 106 | + ], PKCS8_PREFIX.byteLength + seed.byteLength), |
| 107 | + type: 'pkcs8', |
| 108 | + format: 'der' |
| 109 | + }) |
| 110 | + |
| 111 | + const publicKey = crypto.createPublicKey(privateKey) |
| 112 | + .export({ |
| 113 | + type: 'spki', |
| 114 | + format: 'der' |
| 115 | + }).subarray(12) |
| 116 | + |
| 117 | + return { |
| 118 | + publicKey, |
| 119 | + privateKey: seed |
| 120 | + } |
| 121 | + }, |
| 122 | + generateX25519SharedKey (privateKey: Uint8Array, publicKey: Uint8Array): Uint8Array { |
| 123 | + publicKey = uint8ArrayConcat([ |
| 124 | + X25519_PREFIX, |
| 125 | + publicKey |
| 126 | + ], X25519_PREFIX.byteLength + publicKey.byteLength) |
| 127 | + |
| 128 | + privateKey = uint8ArrayConcat([ |
| 129 | + PKCS8_PREFIX, |
| 130 | + privateKey |
| 131 | + ], PKCS8_PREFIX.byteLength + privateKey.byteLength) |
| 132 | + |
| 133 | + return crypto.diffieHellman({ |
| 134 | + publicKey: crypto.createPublicKey({ |
| 135 | + key: Buffer.from(publicKey, publicKey.byteOffset, publicKey.byteLength), |
| 136 | + type: 'spki', |
| 137 | + format: 'der' |
| 138 | + }), |
| 139 | + privateKey: crypto.createPrivateKey({ |
| 140 | + key: Buffer.from(privateKey, privateKey.byteOffset, privateKey.byteLength), |
| 141 | + type: 'pkcs8', |
| 142 | + format: 'der' |
| 143 | + }) |
| 144 | + }) |
79 | 145 | } |
80 | 146 | } |
81 | 147 |
|
|
0 commit comments