@@ -156,4 +156,134 @@ Java_network_loki_messenger_libsession_1util_SessionEncrypt_calculateECHDAgreeme
156
156
return util::bytes_from_span (env, shared_secret);
157
157
});
158
158
159
+ }
160
+
161
+ extern " C"
162
+ JNIEXPORT jlong JNICALL
163
+ Java_network_loki_messenger_libsession_1util_encrypt_EncryptionStream_00024Companion_createEncryptionStreamState (
164
+ JNIEnv *env, jobject thiz, jbyteArray javaKey, jbyteArray javaHeaderOut) {
165
+ JavaByteArrayRef key (env, javaKey);
166
+ JavaByteArrayRef headerOut (env, javaHeaderOut);
167
+
168
+ if (headerOut.get ().size () < crypto_secretstream_xchacha20poly1305_HEADERBYTES) {
169
+ env->ThrowNew (env->FindClass (" java/lang/IllegalArgumentException" ),
170
+ " Invalid headerOut: not enough space" );
171
+ return 0 ;
172
+ }
173
+
174
+ if (key.get ().size () != crypto_secretstream_xchacha20poly1305_KEYBYTES) {
175
+ env->ThrowNew (env->FindClass (" java/lang/IllegalArgumentException" ),
176
+ " Invalid key: unexpected size" );
177
+ return 0 ;
178
+ }
179
+
180
+ auto state = std::make_unique<crypto_secretstream_xchacha20poly1305_state>();
181
+ crypto_secretstream_xchacha20poly1305_init_push (state.get (),
182
+ headerOut.get ().data (),
183
+ key.get ().data ());
184
+
185
+ return reinterpret_cast <jlong>(state.release ());
186
+ }
187
+
188
+ extern " C"
189
+ JNIEXPORT jint JNICALL
190
+ Java_network_loki_messenger_libsession_1util_encrypt_EncryptionStream_00024Companion_encryptionStreamHeaderSize (
191
+ JNIEnv *env, jobject thiz) {
192
+ return static_cast <jint>(crypto_secretstream_xchacha20poly1305_HEADERBYTES);
193
+ }
194
+
195
+ extern " C"
196
+ JNIEXPORT jint JNICALL
197
+ Java_network_loki_messenger_libsession_1util_encrypt_EncryptionStream_00024Companion_encryptionStreamChunkOverhead (
198
+ JNIEnv *env, jobject thiz) {
199
+ return static_cast <jint>(crypto_secretstream_xchacha20poly1305_ABYTES);
200
+ }
201
+
202
+ extern " C"
203
+ JNIEXPORT jint JNICALL
204
+ Java_network_loki_messenger_libsession_1util_encrypt_EncryptionStream_00024Companion_encryptStreamPush (
205
+ JNIEnv *env, jobject thiz, jlong state_ptr, jbyteArray java_in_buf, jint in_buf_size, jbyteArray java_out_buf) {
206
+ auto state = reinterpret_cast <crypto_secretstream_xchacha20poly1305_state*>(state_ptr);
207
+
208
+ JavaByteArrayRef in_buf (env, java_in_buf);
209
+ JavaByteArrayRef out_buf (env, java_out_buf);
210
+
211
+ unsigned long long cipher_len = out_buf.get ().size ();
212
+
213
+ if (crypto_secretstream_xchacha20poly1305_push (
214
+ state,
215
+ out_buf.get ().data (), &cipher_len, // Cipher data out
216
+ in_buf.get ().data (), in_buf_size, // Plaintext data in
217
+ nullptr , 0 , // Additional data (not used here)
218
+ 0 // Tag (not used here, can be 0 for message)
219
+ )) {
220
+ env->ThrowNew (env->FindClass (" java/lang/IllegalStateException" ),
221
+ " Failed to push data into encryption stream" );
222
+ return 0 ;
223
+ }
224
+
225
+ // Return the size of the ciphertext written to the output buffer
226
+ return cipher_len;
227
+ }
228
+
229
+ extern " C"
230
+ JNIEXPORT void JNICALL
231
+ Java_network_loki_messenger_libsession_1util_encrypt_EncryptionStream_00024Companion_destroyEncryptionStreamState (
232
+ JNIEnv *env, jobject thiz, jlong state_ptr) {
233
+ delete reinterpret_cast <crypto_secretstream_xchacha20poly1305_state*>(state_ptr);
234
+ }
235
+
236
+
237
+ extern " C"
238
+ JNIEXPORT jlong JNICALL
239
+ Java_network_loki_messenger_libsession_1util_encrypt_DecryptionStream_00024Companion_createDecryptionStreamState (
240
+ JNIEnv *env, jobject thiz, jbyteArray javaKey, jbyteArray javaHeader) {
241
+ JavaByteArrayRef key (env, javaKey);
242
+ JavaByteArrayRef header (env, javaHeader);
243
+
244
+ if (header.get ().size () < crypto_secretstream_xchacha20poly1305_HEADERBYTES) {
245
+ env->ThrowNew (env->FindClass (" java/lang/IllegalArgumentException" ),
246
+ " Invalid header: unexpected size" );
247
+ return 0 ;
248
+ }
249
+
250
+ if (key.get ().size () != crypto_secretstream_xchacha20poly1305_KEYBYTES) {
251
+ env->ThrowNew (env->FindClass (" java/lang/IllegalArgumentException" ),
252
+ " Invalid key: unexpected size" );
253
+ return 0 ;
254
+ }
255
+
256
+ auto state = std::make_unique<crypto_secretstream_xchacha20poly1305_state>();
257
+
258
+ if (crypto_secretstream_xchacha20poly1305_init_pull (state.get (), header.get ().data (), key.get ().data ()) != 0 ) {
259
+ env->ThrowNew (env->FindClass (" java/lang/IllegalArgumentException" ),
260
+ " Failed to initialize decryption stream state" );
261
+ return 0 ;
262
+ }
263
+
264
+ return reinterpret_cast <jlong>(state.release ());
265
+ }
266
+
267
+ extern " C"
268
+ JNIEXPORT jint JNICALL
269
+ Java_network_loki_messenger_libsession_1util_encrypt_DecryptionStream_00024Companion_decryptionStreamPull (
270
+ JNIEnv *env, jobject thiz, jlong native_state_ptr, jbyteArray java_in_buf, jint in_buf_len, jbyteArray java_out_buf) {
271
+ JavaByteArrayRef out_buf (env, java_out_buf);
272
+ JavaByteArrayRef in_buf (env, java_in_buf);
273
+
274
+ unsigned long long mlen = out_buf.get ().size ();
275
+
276
+ if (crypto_secretstream_xchacha20poly1305_pull (
277
+ reinterpret_cast <crypto_secretstream_xchacha20poly1305_state*>(native_state_ptr),
278
+ out_buf.get ().data (), &mlen, // Plaintext data out
279
+ nullptr , // Tag (not used here)
280
+ in_buf.get ().data (), in_buf_len, // Ciphertext data in
281
+ nullptr , 0 // Additional data (not used here)
282
+ )) {
283
+ env->ThrowNew (env->FindClass (" java/lang/IllegalStateException" ),
284
+ " Failed to pull data from decryption stream" );
285
+ return 0 ;
286
+ }
287
+
288
+ return mlen;
159
289
}
0 commit comments