diff --git a/dependency-reduced-pom.xml b/dependency-reduced-pom.xml new file mode 100644 index 0000000..b481608 --- /dev/null +++ b/dependency-reduced-pom.xml @@ -0,0 +1,83 @@ + + + 4.0.0 + ai.nomyo + nomyo4J + 1.0 + + + + maven-compiler-plugin + 3.13.0 + + + + org.projectlombok + lombok + 1.18.44 + + + + + + maven-surefire-plugin + 3.5.0 + + + maven-shade-plugin + 3.6.2 + + + package + + shade + + + ${project.build.directory}/${project.build.finalName}.jar + true + + + + + + + + + org.projectlombok + lombok + 1.18.44 + provided + + + org.junit.jupiter + junit-jupiter + 5.12.1 + test + + + junit-jupiter-api + org.junit.jupiter + + + junit-jupiter-params + org.junit.jupiter + + + junit-jupiter-engine + org.junit.jupiter + + + + + + + local-repository + http://gamingvm.home.lan:8080/snapshots + + + + UTF-8 + 25 + 25 + + diff --git a/pom.xml b/pom.xml index 9455ff7..2813584 100644 --- a/pom.xml +++ b/pom.xml @@ -36,6 +36,13 @@ + + + local-repository + http://gamingvm.home.lan:8080/snapshots + + + @@ -57,6 +64,23 @@ maven-surefire-plugin 3.5.0 + + org.apache.maven.plugins + maven-shade-plugin + 3.6.2 + + + package + + shade + + + ${project.build.directory}/${project.build.finalName}.jar + true + + + + diff --git a/src/main/java/ai/nomyo/Constants.java b/src/main/java/ai/nomyo/Constants.java index 740532f..7138313 100644 --- a/src/main/java/ai/nomyo/Constants.java +++ b/src/main/java/ai/nomyo/Constants.java @@ -5,7 +5,7 @@ import java.util.Set; /** * Protocol, crypto, and configuration constants. Immutable — used for downgrade detection. */ -public final class Constants { +final class Constants { // ── Protocol Constants ────────────────────────────────────────── diff --git a/src/main/java/ai/nomyo/EncryptedRequest.java b/src/main/java/ai/nomyo/EncryptedRequest.java index 575a0d8..89da47a 100644 --- a/src/main/java/ai/nomyo/EncryptedRequest.java +++ b/src/main/java/ai/nomyo/EncryptedRequest.java @@ -11,7 +11,7 @@ import lombok.Setter; */ @Setter @Getter -public class EncryptedRequest { +class EncryptedRequest { private static final Gson GSON = new GsonBuilder().create(); diff --git a/src/main/java/ai/nomyo/Main.java b/src/main/java/ai/nomyo/Main.java deleted file mode 100644 index 14b7785..0000000 --- a/src/main/java/ai/nomyo/Main.java +++ /dev/null @@ -1,31 +0,0 @@ -package ai.nomyo; - -import java.security.SecureRandom; -import java.util.List; -import java.util.Map; - -/** - * Entry point — loads RSA keys and validates key length. - */ -public class Main { - - static void main() { - SecureChatCompletion secureChatCompletion = new SecureChatCompletion(Constants.DEFAULT_BASE_URL, "NOMYO_AI_E2EE_INFERENCE"); - List> messages = List.of( - Map.of("role", "user", "content", "Hello! How are you today?") - ); - - Map kwargs = Map.of( - "security_tier", "standard", - "temperature", 0.7 - ); - - var response = secureChatCompletion.create( - "Qwen/Qwen3-0.6B", - messages, - kwargs); - - System.out.println(response.toString()); - - } -} diff --git a/src/main/java/ai/nomyo/util/Pass2Key.java b/src/main/java/ai/nomyo/Pass2Key.java similarity index 99% rename from src/main/java/ai/nomyo/util/Pass2Key.java rename to src/main/java/ai/nomyo/Pass2Key.java index e82420e..2b333df 100644 --- a/src/main/java/ai/nomyo/util/Pass2Key.java +++ b/src/main/java/ai/nomyo/Pass2Key.java @@ -1,6 +1,5 @@ -package ai.nomyo.util; +package ai.nomyo; -import ai.nomyo.SecureMemory; import ai.nomyo.SecureMemory.SecureBuffer; import ai.nomyo.errors.SecurityError; @@ -13,7 +12,6 @@ import javax.crypto.SecretKeyFactory; import javax.crypto.spec.GCMParameterSpec; import javax.crypto.spec.PBEKeySpec; import javax.crypto.spec.SecretKeySpec; -import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; import java.security.*; import java.security.spec.InvalidKeySpecException; diff --git a/src/main/java/ai/nomyo/SecureCompletionClient.java b/src/main/java/ai/nomyo/SecureCompletionClient.java index 1d702de..486afef 100644 --- a/src/main/java/ai/nomyo/SecureCompletionClient.java +++ b/src/main/java/ai/nomyo/SecureCompletionClient.java @@ -2,7 +2,6 @@ package ai.nomyo; import ai.nomyo.errors.*; import ai.nomyo.util.PEMConverter; -import ai.nomyo.util.Pass2Key; import ai.nomyo.SecureMemory.SecureBuffer; import lombok.Getter; @@ -40,7 +39,7 @@ import java.util.concurrent.locks.ReentrantLock; /** * Low-level client: key management, hybrid encryption, HTTP with retry, response decryption. Used by {@link SecureChatCompletion}. */ -public class SecureCompletionClient { +class SecureCompletionClient { /** * NOMYO router base URL (trailing slash stripped). @@ -405,9 +404,10 @@ public class SecureCompletionClient { throw new RuntimeException(new SecurityError("RSA-OAEP key wrapping failed: " + e.getMessage(), e)); } - String encryptedAESKeyB64 = Base64.getEncoder().encodeToString(encryptedAESKey); - try (SecureBuffer secureEncryptedAESKey = SecureMemory.secureByteArray(encryptedAESKey)) { + + Arrays.fill(encryptedAESKey, (byte) 0); + byte[] tag = Arrays.copyOfRange(ciphertext, ciphertext.length - Constants.GCM_TAG_SIZE, ciphertext.length); byte[] actualCiphertext = Arrays.copyOf(ciphertext, ciphertext.length - Constants.GCM_TAG_SIZE); @@ -416,13 +416,11 @@ public class SecureCompletionClient { request.setVersion(Constants.PROTOCOL_VERSION); request.setAlgorithm(Constants.HYBRID_ALGORITHM); - request.setEncryptedPayload(new EncryptedRequest.EncryptedPayload(Base64.getEncoder().encodeToString(actualCiphertext), encryptedAESKeyB64, Base64.getEncoder().encodeToString(tag))); - request.setEncryptedAESKey(encryptedAESKeyB64); + request.setEncryptedPayload(new EncryptedRequest.EncryptedPayload(Base64.getEncoder().encodeToString(actualCiphertext), Base64.getEncoder().encodeToString(secureNonce.getAsByteArray()), Base64.getEncoder().encodeToString(tag))); + request.setEncryptedAESKey(Base64.getEncoder().encodeToString(secureEncryptedAESKey.getAsByteArray())); request.setKeyAlgorithm(Constants.KEY_WRAP_ALGORITHM); request.setPayloadAlgorithm(Constants.PAYLOAD_ALGORITHM); - Arrays.fill(encryptedAESKey, (byte) 0); - return request.toJson().getBytes(StandardCharsets.UTF_8); } } diff --git a/src/main/java/ai/nomyo/SecureMemory.java b/src/main/java/ai/nomyo/SecureMemory.java index d06c486..4f31d5f 100644 --- a/src/main/java/ai/nomyo/SecureMemory.java +++ b/src/main/java/ai/nomyo/SecureMemory.java @@ -12,7 +12,7 @@ import java.util.Map; * Cross-platform memory locking and secure zeroing for sensitive cryptographic buffers. Fails gracefully if unavailable. */ @SuppressWarnings("SameReturnValue") -public final class SecureMemory { +final class SecureMemory { @Getter private static final boolean HAS_MEMORY_LOCKING; diff --git a/src/test/java/ai/nomyo/SecureCompletionClientTest.java b/src/test/java/ai/nomyo/SecureCompletionClientTest.java index 78eb39f..ca79485 100644 --- a/src/test/java/ai/nomyo/SecureCompletionClientTest.java +++ b/src/test/java/ai/nomyo/SecureCompletionClientTest.java @@ -1,7 +1,6 @@ package ai.nomyo; import ai.nomyo.errors.SecurityError; -import ai.nomyo.util.Pass2Key; import org.junit.jupiter.api.*; import org.junit.jupiter.api.io.TempDir; import org.junit.jupiter.api.parallel.Execution;