Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/main/c/KEMs.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ JNIEXPORT jint JNICALL Java_org_openquantumsafe_KEMs_max_1number_1KEMs
JNIEXPORT jboolean JNICALL Java_org_openquantumsafe_KEMs_is_1KEM_1enabled
(JNIEnv *env, jclass cls, jstring java_str)
{
if (java_str == NULL) return JNI_FALSE;
const char *str_native = (*env)->GetStringUTFChars(env, java_str, 0);
int is_enabled = OQS_KEM_alg_is_enabled (str_native);
(*env)->ReleaseStringUTFChars(env, java_str, str_native);
Expand Down
2 changes: 2 additions & 0 deletions src/main/c/KeyEncapsulation.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
JNIEXPORT void JNICALL Java_org_openquantumsafe_KeyEncapsulation_create_1KEM_1new
(JNIEnv *env, jobject obj, jstring jstr)
{
if (jstr == NULL) return;

// Create get a liboqs::OQS_KEM pointer
const char *str_native = (*env)->GetStringUTFChars(env, jstr, 0);
OQS_KEM *kem = OQS_KEM_new(str_native);
Expand Down
1 change: 1 addition & 0 deletions src/main/c/Rand.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ JNIEXPORT jbyteArray JNICALL Java_org_openquantumsafe_Rand_randombytes
JNIEXPORT jint JNICALL Java_org_openquantumsafe_Rand_randombytes_1switch_1algorithm_1native
(JNIEnv *env, jclass cls, jstring jstr)
{
if (jstr == NULL) return -1;
const char *alg_name_native = (*env)->GetStringUTFChars(env, jstr, 0);
int rv_ = OQS_randombytes_switch_algorithm(alg_name_native);
(*env)->ReleaseStringUTFChars(env, jstr, alg_name_native);
Expand Down
16 changes: 10 additions & 6 deletions src/main/c/Signature.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
JNIEXPORT void JNICALL Java_org_openquantumsafe_Signature_create_1sig_1new
(JNIEnv *env, jobject obj, jstring jstr)
{
if (jstr == NULL) return;

// Create get a liboqs::OQS_SIG pointer
const char *str_native = (*env)->GetStringUTFChars(env, jstr, 0);
OQS_SIG *sig = OQS_SIG_new(str_native);
Expand Down Expand Up @@ -121,7 +123,7 @@ JNIEXPORT jint JNICALL Java_org_openquantumsafe_Signature_sign
jbyte *secret_key_native = (*env)->GetByteArrayElements(env, jsecret_key, 0);

OQS_SIG *sig = (OQS_SIG *) getHandle(env, obj, "native_sig_handle_");
size_t len_sig;
size_t len_sig = 0;

OQS_STATUS rv_ = OQS_SIG_sign(sig, (uint8_t*)signature_native, &len_sig,
(uint8_t*)message_native, message_len,
Expand Down Expand Up @@ -188,11 +190,12 @@ JNIEXPORT jint JNICALL Java_org_openquantumsafe_Signature_sign_1with_1ctx_1str
// Convert to jbyte arrays
jbyte *signature_native = (*env)->GetByteArrayElements(env, jsignature, 0);
jbyte *message_native = (*env)->GetByteArrayElements(env, jmessage, 0);
jbyte *ctx_native = (*env)->GetByteArrayElements(env, jctx, 0);
// A null ctx means no context string
jbyte *ctx_native = (jctx == NULL) ? NULL : (*env)->GetByteArrayElements(env, jctx, 0);
jbyte *secret_key_native = (*env)->GetByteArrayElements(env, jsecret_key, 0);

OQS_SIG *sig = (OQS_SIG *) getHandle(env, obj, "native_sig_handle_");
size_t len_sig;
size_t len_sig = 0;
OQS_STATUS rv_ = OQS_SIG_sign_with_ctx_str(sig, (uint8_t*)signature_native, &len_sig,
(uint8_t*)message_native, message_len,
(uint8_t*)ctx_native, ctx_len,
Expand All @@ -214,7 +217,7 @@ JNIEXPORT jint JNICALL Java_org_openquantumsafe_Signature_sign_1with_1ctx_1str
// Release C memory
(*env)->ReleaseByteArrayElements(env, jsignature, signature_native, 0);
(*env)->ReleaseByteArrayElements(env, jmessage, message_native, JNI_ABORT);
(*env)->ReleaseByteArrayElements(env, jctx, ctx_native, JNI_ABORT);
if (jctx != NULL) (*env)->ReleaseByteArrayElements(env, jctx, ctx_native, JNI_ABORT);
(*env)->ReleaseByteArrayElements(env, jsecret_key, secret_key_native, JNI_ABORT);

return (rv_ == OQS_SUCCESS) ? 0 : -1;
Expand All @@ -233,7 +236,8 @@ JNIEXPORT jboolean JNICALL Java_org_openquantumsafe_Signature_verify_1with_1ctx_
// Convert to jbyte arrays
jbyte *message_native = (*env)->GetByteArrayElements(env, jmessage, 0);
jbyte *signature_native = (*env)->GetByteArrayElements(env, jsignature, 0);
jbyte *ctx_native = (*env)->GetByteArrayElements(env, jctx, 0);
// A null ctx means no context string
jbyte *ctx_native = (jctx == NULL) ? NULL : (*env)->GetByteArrayElements(env, jctx, 0);
jbyte *public_key_native = (*env)->GetByteArrayElements(env, jpublic_key, 0);

OQS_SIG *sig = (OQS_SIG *) getHandle(env, obj, "native_sig_handle_");
Expand All @@ -245,7 +249,7 @@ JNIEXPORT jboolean JNICALL Java_org_openquantumsafe_Signature_verify_1with_1ctx_
// Release C memory
(*env)->ReleaseByteArrayElements(env, jsignature, signature_native, JNI_ABORT);
(*env)->ReleaseByteArrayElements(env, jmessage, message_native, JNI_ABORT);
(*env)->ReleaseByteArrayElements(env, jctx, ctx_native, JNI_ABORT);
if (jctx != NULL) (*env)->ReleaseByteArrayElements(env, jctx, ctx_native, JNI_ABORT);
(*env)->ReleaseByteArrayElements(env, jpublic_key, public_key_native, JNI_ABORT);

return (rv_ == OQS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
Expand Down
1 change: 1 addition & 0 deletions src/main/c/Sigs.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ JNIEXPORT jint JNICALL Java_org_openquantumsafe_Sigs_max_1number_1sigs
JNIEXPORT jboolean JNICALL Java_org_openquantumsafe_Sigs_is_1sig_1enabled
(JNIEnv *env, jclass cls, jstring jstr)
{
if (jstr == NULL) return JNI_FALSE;
const char *str_native = (*env)->GetStringUTFChars(env, jstr, 0);
int is_enabled = OQS_SIG_alg_is_enabled (str_native);
(*env)->ReleaseStringUTFChars(env, jstr, str_native);
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/org/openquantumsafe/Signature.java
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ public boolean verify(byte[] message, byte[] signature, byte[] public_key)
/**
* \brief Invoke native sign method
* \param message
* \param ctx
* \param ctx Context string, or null for no context
* \return signature
*/
public byte[] sign(byte[] message, byte[] ctx) throws RuntimeException {
Expand Down Expand Up @@ -297,7 +297,7 @@ public byte[] sign(byte[] message, byte[] ctx) throws RuntimeException {
* \brief Invoke native verify method
* \param message
* \param signature
* \param ctx
* \param ctx Context string, or null for no context
* \param public_key
* \return True if the signature is valid, false otherwise
*/
Expand Down
23 changes: 23 additions & 0 deletions src/test/java/org/openquantumsafe/KEMTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,29 @@ public void testUnsupportedKEMExpectedException() {
Assertions.assertThrows(MechanismNotSupportedError.class, () -> new KeyEncapsulation("MechanismNotSupported"));
}

/**
* Test that a null algorithm name is rejected like an unsupported one
*/
@Test
public void testNullKEMNameExpectedException() {
Assertions.assertThrows(MechanismNotSupportedError.class, () -> new KeyEncapsulation(null));
}

/**
* Test that a null algorithm name leaves the existing mechanism in place
*/
@Test
public void testCreateKEMNewWithNullName() {
KeyEncapsulation client = new KeyEncapsulation("ML-KEM-512");
KeyEncapsulation server = new KeyEncapsulation("ML-KEM-512");
byte[] client_public_key = client.generate_keypair();

client.create_KEM_new(null);

Pair<byte[], byte[]> server_pair = server.encap_secret(client_public_key);
assertArrayEquals(client.decap_secret(server_pair.getLeft()), server_pair.getRight());
}

/**
* Method to convert the list of KEMs to a stream for input to testAllKEMs
*/
Expand Down
17 changes: 17 additions & 0 deletions src/test/java/org/openquantumsafe/RandTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package org.openquantumsafe;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

public class RandTest {

/**
* Test that a null algorithm name is rejected
*/
@Test
public void testNullRandAlgExpectedException() {
RuntimeException e = Assertions.assertThrows(RuntimeException.class,
() -> Rand.randombytes_switch_algorithm(null));
Assertions.assertEquals("Cannot switch rand algorithm", e.getMessage());
}
}
62 changes: 62 additions & 0 deletions src/test/java/org/openquantumsafe/SigTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import org.junit.jupiter.params.provider.MethodSource;

// import static org.junit.Assert.fail;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;

import java.util.ArrayList;
Expand Down Expand Up @@ -88,6 +89,46 @@ public void testSigsWithContext(String sig_name) {
System.out.println(sb.toString());
}

/**
* Test that a null context means no context
*/
@ParameterizedTest(name = "Testing {arguments}")
@MethodSource("getContextSupportedAlgsAsStream")
public void testSigsWithNullContext(String sig_name) {
byte[] context = "01234567890".getBytes();

// Create signer and verifier
Signature signer = new Signature(sig_name);
Signature verifier = new Signature(sig_name);

// Generate signer key pair
byte[] signer_public_key = signer.generate_keypair();

// A null context signature verifies as a signature without context
byte[] signature = signer.sign(message, null);
assertTrue(verifier.verify(message, signature, signer_public_key), sig_name);
assertTrue(verifier.verify(message, signature, null, signer_public_key), sig_name);

// A signature with a context does not verify under a null context
byte[] context_signature = signer.sign(message, context);
assertFalse(verifier.verify(message, context_signature, null, signer_public_key), sig_name);
}

/**
* Test that a failed signing operation is reported as such. ML-DSA limits
* the context to 255 bytes.
*/
@ParameterizedTest(name = "Testing {arguments}")
@MethodSource("getContextSupportedAlgsAsStream")
public void testContextTooLongExpectedException(String sig_name) {
Signature signer = new Signature(sig_name);
signer.generate_keypair();

RuntimeException e = Assertions.assertThrows(RuntimeException.class,
() -> signer.sign(message, new byte[256]));
Assertions.assertEquals("Cannot sign message", e.getMessage());
}

/**
* Test the MechanismNotSupported Exception
*/
Expand All @@ -96,6 +137,27 @@ public void testUnsupportedSigExpectedException() {
Assertions.assertThrows(MechanismNotSupportedError.class, () -> new Signature("MechanismNotSupported"));
}

/**
* Test that a null algorithm name is rejected like an unsupported one
*/
@Test
public void testNullSigNameExpectedException() {
Assertions.assertThrows(MechanismNotSupportedError.class, () -> new Signature(null));
}

/**
* Test that a null algorithm name leaves the existing mechanism in place
*/
@Test
public void testCreateSigNewWithNullName() {
Signature signer = new Signature("ML-DSA-44");
byte[] signer_public_key = signer.generate_keypair();

signer.create_sig_new(null);

assertTrue(signer.verify(message, signer.sign(message), signer_public_key));
}

/**
* Method to convert the list of Sigs to a stream for input to testAllSigs
*/
Expand Down
Loading