shogun-core 6.2.2 → 6.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -125,6 +125,11 @@ const performDHRatchetStep = async (state, newRemotePublicKey) => {
|
|
|
125
125
|
// Generate our sending key pair for future messages
|
|
126
126
|
console.log("🔑 Generating DH key pair for responder's future sending");
|
|
127
127
|
state.sendingDHKeyPair = await (0, signal_protocol_1.generateSignalKeyPair)();
|
|
128
|
+
// For responder's first receive, we don't derive a sending chain yet
|
|
129
|
+
// because we haven't sent anything. The sending chain will be derived
|
|
130
|
+
// when we send our first message.
|
|
131
|
+
console.log("✓ DH ratchet step completed (responder first receive)");
|
|
132
|
+
return;
|
|
128
133
|
}
|
|
129
134
|
else if (state.sendingDHKeyPair) {
|
|
130
135
|
console.log("🔄 Deriving receiving chain from: DH(our_current_private, their_public)");
|
|
@@ -136,6 +141,7 @@ const performDHRatchetStep = async (state, newRemotePublicKey) => {
|
|
|
136
141
|
console.log("🔄 DH ratchet step - receiving chain established");
|
|
137
142
|
}
|
|
138
143
|
// Step 2: Generate NEW DH key pair and derive sending chain
|
|
144
|
+
// This only executes for subsequent ratchet steps (not responder's first receive)
|
|
139
145
|
console.log("🔑 Generating NEW DH key pair for ratchet step");
|
|
140
146
|
state.sendingDHKeyPair = await (0, signal_protocol_1.generateSignalKeyPair)();
|
|
141
147
|
state.sendingMessageNumber = 0;
|
|
@@ -172,8 +178,24 @@ const skipMessageKeys = async (state, until) => {
|
|
|
172
178
|
// Encrypt message using Double Ratchet
|
|
173
179
|
const doubleRatchetEncrypt = async (state, plaintext) => {
|
|
174
180
|
console.log(`🔒 Encrypting message #${state.sendingMessageNumber} with Double Ratchet`);
|
|
181
|
+
// If responder is sending first message, derive sending chain
|
|
175
182
|
if (!state.sendingChainKey) {
|
|
176
|
-
|
|
183
|
+
if (!state.isInitiator &&
|
|
184
|
+
state.receivingDHPublicKey &&
|
|
185
|
+
state.sendingDHKeyPair) {
|
|
186
|
+
console.log("🔄 Responder's first send: Deriving sending chain");
|
|
187
|
+
// Derive sending chain from our sending DH key pair and their receiving DH public key
|
|
188
|
+
const sendingDHOutput = await (0, signal_protocol_1.performSignalDH)(state.sendingDHKeyPair.privateKey, state.receivingDHPublicKey);
|
|
189
|
+
const hkdfSending = await doubleRatchetHKDF(new Uint8Array(state.rootKey), sendingDHOutput, DOUBLE_RATCHET_INFO_CHAIN_KEY, 64);
|
|
190
|
+
state.rootKey = hkdfSending.slice(0, 32);
|
|
191
|
+
state.sendingChainKey = hkdfSending.slice(32, 64);
|
|
192
|
+
state.sendingMessageNumber = 0;
|
|
193
|
+
state.previousChainLength = state.receivingMessageNumber;
|
|
194
|
+
console.log("✅ Sending chain derived for responder's first message");
|
|
195
|
+
}
|
|
196
|
+
else {
|
|
197
|
+
throw new Error("No sending chain key available - cannot encrypt");
|
|
198
|
+
}
|
|
177
199
|
}
|
|
178
200
|
// Derive message key
|
|
179
201
|
const messageKey = await deriveMessageKey(state.sendingChainKey);
|
|
@@ -149,7 +149,8 @@ exports.importSignalPublicKey = importSignalPublicKey;
|
|
|
149
149
|
const importSignalSigningPublicKey = async (keyBytes) => {
|
|
150
150
|
return await crypto.subtle.importKey("raw", keyBytes, {
|
|
151
151
|
name: "Ed25519",
|
|
152
|
-
},
|
|
152
|
+
}, true, // Make public keys extractable for re-export in bundles
|
|
153
|
+
["verify"]);
|
|
153
154
|
};
|
|
154
155
|
exports.importSignalSigningPublicKey = importSignalSigningPublicKey;
|
|
155
156
|
const performSignalDH = async (privateKey, publicKey) => {
|