1
- import * as defaultCrypto from '#crypto' ;
2
- import { clearBuffer , isBuffer } from '@universalweb/acid' ;
1
+ import {
2
+ clearBuffer ,
3
+ int32 ,
4
+ randomBuffer
5
+ } from '#crypto' ;
6
+ import { isBuffer } from '@universalweb/acid' ;
3
7
import { ml_kem768 } from '@noble/post-quantum/ml-kem' ;
4
- import { encryptionKeypair as x25519Keypair } from './x25519.js' ;
5
- const { randomBuffer } = defaultCrypto ;
8
+ import { shake256 } from '@noble/hashes/sha3' ;
9
+ const hashFunction = shake256 ;
10
+ const sessionKeySize = int32 ;
11
+ const hashSettings = {
12
+ dkLen : 64
13
+ } ;
6
14
export async function encryptionKeypair ( seed ) {
7
15
const kyberKeypair = ml_kem768 . keygen ( seed ) ;
8
16
return {
9
17
publicKey : kyberKeypair . publicKey ,
10
18
privateKey : kyberKeypair . secretKey
11
19
} ;
12
20
}
13
- export async function decapsulate ( cipherText , sourceKeypairKyber ) {
14
- const decapsulated = ml_kem768 . decapsulate ( cipherText , sourceKeypairKyber ?. privateKey || sourceKeypairKyber ) ;
21
+ export async function decapsulate ( cipherData , sourceKeypairKyber ) {
22
+ const decapsulated = ml_kem768 . decapsulate ( cipherData , sourceKeypairKyber ?. privateKey || sourceKeypairKyber ) ;
15
23
return decapsulated ;
16
24
}
25
+ export function clientSetSession ( client , server , target , cipherData ) {
26
+ const sharedSecret = decapsulate ( cipherData , client . privateKey ) ;
27
+ const hashSharedSecret = hashFunction ( Buffer . concat ( [
28
+ sharedSecret ,
29
+ client . publicKey ,
30
+ server ?. publicKey || server
31
+ ] ) , hashSettings ) ;
32
+ const transmitKey = hashSharedSecret . subarray ( sessionKeySize ) ;
33
+ const receiveKey = hashSharedSecret . subarray ( 0 , sessionKeySize ) ;
34
+ if ( target ) {
35
+ target . sharedSecret = hashSharedSecret ;
36
+ target . receiveKey = receiveKey ;
37
+ target . transmitKey = transmitKey ;
38
+ return target ;
39
+ }
40
+ return {
41
+ sharedSecret : hashSharedSecret ,
42
+ receiveKey,
43
+ transmitKey
44
+ } ;
45
+ }
46
+ export function serverSetSession ( server , client , target , cipherData ) {
47
+ const sharedSecret = decapsulate ( cipherData , server . privateKey ) ;
48
+ const hashSharedSecret = hashFunction ( Buffer . concat ( [
49
+ sharedSecret ,
50
+ client ?. publicKey || client ,
51
+ server . publicKey
52
+ ] ) , hashSettings ) ;
53
+ const transmitKey = hashSharedSecret . subarray ( 0 , sessionKeySize ) ;
54
+ const receiveKey = hashSharedSecret . subarray ( sessionKeySize ) ;
55
+ if ( target ) {
56
+ target . sharedSecret = hashSharedSecret ;
57
+ target . receiveKey = receiveKey ;
58
+ target . transmitKey = transmitKey ;
59
+ return target ;
60
+ }
61
+ return {
62
+ sharedSecret : hashSharedSecret ,
63
+ receiveKey,
64
+ transmitKey
65
+ } ;
66
+ }
17
67
export async function encapsulate ( sourceKeypair ) {
18
68
// { cipherText, sharedSecret }
19
69
const encapsulated = ml_kem768 . encapsulate ( sourceKeypair ?. publicKey || sourceKeypair ) ;
@@ -32,6 +82,7 @@ export const kyber768 = {
32
82
clientPrivateKeySize : privateKeySize ,
33
83
serverPublicKeySize : publicKeySize ,
34
84
serverPrivateKeySize : privateKeySize ,
85
+ sessionKeySize,
35
86
ml_kem768,
36
87
decapsulate,
37
88
encapsulate,
0 commit comments