Skip to content

Commit e342822

Browse files
SessionHero01SessionHero01
authored andcommitted
Hashing and other bindings
1 parent 7c32460 commit e342822

File tree

8 files changed

+168
-0
lines changed

8 files changed

+168
-0
lines changed

library/src/main/cpp/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ set(SOURCES
4343
jni_utils.cpp
4444
ed25519.cpp
4545
curve25519.cpp
46+
hash.cpp
4647
)
4748

4849
add_library( # Sets the name of the library.

library/src/main/cpp/blinded_key.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,4 +73,38 @@ Java_network_loki_messenger_libsession_1util_util_BlindKeyAPI_blind15KeyPair(JNI
7373
);
7474
return jni_utils::new_key_pair(env, util::bytes_from_span(env, pk), util::bytes_from_span(env, sk));
7575
});
76+
}
77+
78+
extern "C"
79+
JNIEXPORT jbyteArray JNICALL
80+
Java_network_loki_messenger_libsession_1util_util_BlindKeyAPI_blind15Sign(JNIEnv *env, jobject thiz,
81+
jbyteArray ed25519_secret_key,
82+
jstring server_pub_key,
83+
jbyteArray message) {
84+
return jni_utils::run_catching_cxx_exception_or_throws<jbyteArray>(env, [=] {
85+
auto data = session::blind15_sign(
86+
jni_utils::JavaByteArrayRef(env, ed25519_secret_key).get(),
87+
jni_utils::JavaStringRef(env, server_pub_key).view(),
88+
jni_utils::JavaByteArrayRef(env, message).get()
89+
);
90+
return util::bytes_from_vector(env, data);
91+
});
92+
}
93+
94+
extern "C"
95+
JNIEXPORT jboolean JNICALL
96+
Java_network_loki_messenger_libsession_1util_util_BlindKeyAPI_sessionIdMatchesBlindedId(JNIEnv *env,
97+
jobject thiz,
98+
jstring session_id,
99+
jstring blinded_id,
100+
jstring server_pub_key) {
101+
return jni_utils::run_catching_cxx_exception_or<jboolean>([=]() -> jboolean {
102+
return session::session_id_matches_blinded_id(
103+
jni_utils::JavaStringRef(env, session_id).view(),
104+
jni_utils::JavaStringRef(env, blinded_id).view(),
105+
jni_utils::JavaStringRef(env, server_pub_key).view()
106+
);
107+
}, [](const char *) -> jboolean {
108+
return false;
109+
});
76110
}

library/src/main/cpp/encryption.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,4 +91,38 @@ Java_network_loki_messenger_libsession_1util_SessionEncrypt_encryptForBlindedRec
9191

9292
return jni_utils::session_bytes_from_range(env, data);
9393
});
94+
}
95+
96+
extern "C"
97+
JNIEXPORT jobject JNICALL
98+
Java_network_loki_messenger_libsession_1util_SessionEncrypt_decryptPushNotification(JNIEnv *env,
99+
jobject thiz,
100+
jbyteArray message,
101+
jbyteArray secret_key) {
102+
return jni_utils::run_catching_cxx_exception_or_throws<jobject>(env, [=] {
103+
auto data = session::decrypt_push_notification(
104+
jni_utils::JavaByteArrayRef(env, message).get(),
105+
jni_utils::JavaByteArrayRef(env, secret_key).get()
106+
);
107+
108+
return jni_utils::session_bytes_from_range(env, data);
109+
});
110+
}
111+
112+
extern "C"
113+
JNIEXPORT jstring JNICALL
114+
Java_network_loki_messenger_libsession_1util_SessionEncrypt_decryptOnsResponse(JNIEnv *env,
115+
jobject thiz,
116+
jstring lowercase_name,
117+
jbyteArray ciphertext,
118+
jbyteArray nonce) {
119+
return jni_utils::run_catching_cxx_exception_or_throws<jstring>(env, [=] {
120+
auto data = session::decrypt_ons_response(
121+
jni_utils::JavaStringRef(env, lowercase_name).view(),
122+
jni_utils::JavaByteArrayRef(env, ciphertext).get(),
123+
nonce ? std::make_optional(jni_utils::JavaByteArrayRef(env, nonce).get()) : std::nullopt
124+
);
125+
126+
return util::jstringFromOptional(env, data);
127+
});
94128
}

library/src/main/cpp/hash.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#include "jni_utils.h"
2+
3+
#include <session/hash.hpp>
4+
5+
extern "C"
6+
JNIEXPORT void JNICALL
7+
Java_network_loki_messenger_libsession_1util_Hash_hash(JNIEnv *env, jobject thiz,
8+
jbyteArray message,
9+
jbyteArray hashOut,
10+
jbyteArray key) {
11+
jni_utils::run_catching_cxx_exception_or_throws<void>(env, [=] {
12+
session::hash::hash(
13+
jni_utils::JavaByteArrayRef(env, hashOut).get(),
14+
jni_utils::JavaByteArrayRef(env, message).get(),
15+
key ? std::make_optional(jni_utils::JavaByteArrayRef(env, key).get()) : std::nullopt);
16+
});
17+
}

library/src/main/cpp/jni_utils.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,32 @@ namespace jni_utils {
151151
*/
152152
jobject new_key_pair(JNIEnv *env, jbyteArray pubKey, jbyteArray secKey);
153153

154+
class JavaStringRef {
155+
JNIEnv *env;
156+
jstring s;
157+
std::span<char> data;
158+
159+
public:
160+
JavaStringRef(JNIEnv *env, jstring s) : env(env), s(s) {
161+
const char *c_str = env->GetStringUTFChars(s, nullptr);
162+
data = std::span<char>(const_cast<char *>(c_str), env->GetStringUTFLength(s));
163+
}
164+
165+
~JavaStringRef() {
166+
env->ReleaseStringUTFChars(s, data.data());
167+
}
168+
169+
// Get the data as a string view. Only valid during the lifetime of this object.
170+
std::string_view view() const {
171+
return std::string_view(data.data(), data.size());
172+
}
173+
174+
// Get the data as a span. Only valid during the lifetime of this object.
175+
std::span<char> get() const {
176+
return data;
177+
}
178+
};
179+
154180
/**
155181
* A RAII wrapper for a Java byte array. This will automatically release the byte array when it goes out of scope.
156182
*/
@@ -169,6 +195,7 @@ namespace jni_utils {
169195
env->ReleaseByteArrayElements(byte_array, reinterpret_cast<jbyte *>(data.data()), 0);
170196
}
171197

198+
// Get the data as a span. Only valid during the lifetime of this object.
172199
std::span<unsigned char> get() const {
173200
return data;
174201
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package network.loki.messenger.libsession_util
2+
3+
object Hash {
4+
private external fun hash(message: ByteArray, hashOut: ByteArray, key: ByteArray?)
5+
6+
fun hash64(message: ByteArray, key: ByteArray? = null): ByteArray {
7+
val hashOut = ByteArray(64)
8+
hash(message, hashOut, key)
9+
return hashOut
10+
}
11+
12+
fun hash32(message: ByteArray, key: ByteArray? = null): ByteArray {
13+
val hashOut = ByteArray(32)
14+
hash(message, hashOut, key)
15+
return hashOut
16+
}
17+
}

library/src/main/java/network/loki/messenger/libsession_util/SessionEncrypt.kt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,4 +66,15 @@ object SessionEncrypt {
6666
x25519PrivKey: ByteArray,
6767
ciphertext: ByteArray
6868
): Pair<SessionId, Bytes>
69+
70+
external fun decryptPushNotification(
71+
message: ByteArray,
72+
secretKey: ByteArray,
73+
): Bytes
74+
75+
external fun decryptOnsResponse(
76+
lowercaseName: String,
77+
ciphertext: ByteArray,
78+
nonce: ByteArray?,
79+
): SessionId
6980
}

library/src/main/java/network/loki/messenger/libsession_util/util/BlindKeyAPI.kt

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,31 @@ object BlindKeyAPI {
3737
ed25519SecretKey: ByteArray,
3838
serverPubKey: ByteArray,
3939
): KeyPair? = kotlin.runCatching { blind15KeyPair(ed25519SecretKey, serverPubKey) }.getOrNull()
40+
41+
/**
42+
* Sign a message with a 15 blinded key.
43+
*
44+
* @param ed25519SecretKey The Ed25519 secret key, 32/64 bytes
45+
* @param serverPubKey The server public key in hex
46+
* @param message The message to sign
47+
*/
48+
external fun blind15Sign(
49+
ed25519SecretKey: ByteArray,
50+
serverPubKey: String,
51+
message: ByteArray,
52+
): ByteArray
53+
54+
/**
55+
* Takes in a standard sessionId and returns a flag indicating whether it matches the given
56+
* blindedId for a given serverPubKey
57+
*
58+
* @param sessionId The session ID to check, 66bytes string
59+
* @param blindedId The blinded ID to check against, 66bytes string
60+
* @param serverPubKey The server public key, 64bytes string
61+
*/
62+
external fun sessionIdMatchesBlindedId(
63+
sessionId: String,
64+
blindedId: String,
65+
serverPubKey: String,
66+
): Boolean
4067
}

0 commit comments

Comments
 (0)