Skip to content

Commit

Permalink
Add interoperability tests
Browse files Browse the repository at this point in the history
  • Loading branch information
muzzammilshahid committed Feb 29, 2024
1 parent 7177226 commit 2b73ba0
Show file tree
Hide file tree
Showing 2 changed files with 106 additions and 0 deletions.
1 change: 1 addition & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ dependencies {
implementation 'org.bouncycastle:bcprov-jdk18on:1.77'
testImplementation platform('org.junit:junit-bom:5.9.1')
testImplementation 'org.junit.jupiter:junit-jupiter'
testImplementation 'org.purejava:tweetnacl-java:1.1.2'
}

test {
Expand Down
105 changes: 105 additions & 0 deletions src/test/java/io/xconn/cryptobox/InteroperabilityTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
package io.xconn.cryptobox;

import java.security.GeneralSecurityException;
import java.util.Arrays;

import com.iwebpp.crypto.TweetNaclFast;

import org.bouncycastle.util.encoders.Hex;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertArrayEquals;

public class InteroperabilityTest {

private static final byte[] publicKey = Hex.decode("e54e7c4f75ea1cba7b276711ad2e88e7ac963502906724b86794d115df85114b");
private static final byte[] privateKey = Hex.decode("28cf2aaeca5db014927f3956ac3c32141b9a08164367326b549b36bc81c3ac48");

@Test
public void secretBoxTest() {
byte[] message = "Hello, World!".getBytes();
byte[] nonce = Util.generateRandomBytesArray(Util.NONCE_SIZE);

// encrypt using TweetNaCl
TweetNaclFast.SecretBox box = new TweetNaclFast.SecretBox(privateKey);
byte[] ct = box.box(message, nonce);

byte[] ciphertext = new byte[nonce.length + ct.length];
System.arraycopy(nonce, 0, ciphertext, 0, nonce.length);
System.arraycopy(ct, 0, ciphertext, nonce.length, ct.length);

// decrypt using SecretBox
byte[] plainText = SecretBox.boxOpen(ciphertext, privateKey);

assertArrayEquals(message, plainText);

// encrypt using SecretBox
byte[] cipherText = SecretBox.box(message, privateKey);

byte[] nonce1 = Arrays.copyOfRange(cipherText, 0, Util.NONCE_SIZE);
byte[] encryptedMessage = Arrays.copyOfRange(cipherText, Util.NONCE_SIZE, cipherText.length);

// decrypt using TweetNaCl
byte[] decryptedMessage = box.open(encryptedMessage, nonce1);
assertArrayEquals(message, decryptedMessage);
}

@Test
public void sealedBoxTest() throws GeneralSecurityException {
byte[] message = "Hello, World!".getBytes();

// encrypt using TweetNaCl
byte[] ct = SealedBoxNaCl.crypto_box_seal(message);

// decrypt using SealedBox
byte[] plainText = SealedBox.sealOpen(ct, privateKey);

assertArrayEquals(message, plainText);

// encrypt using SealedBox
byte[] cipherText = SealedBox.seal(message, publicKey);

// decrypt using TweetNaCl
byte[] plaintext = SealedBoxNaCl.crypto_box_seal_open(cipherText, publicKey, privateKey);

assertArrayEquals(message, plaintext);
}

/**
* An implementation SealedBox using TweetNaCl.
* Taken from https://stackoverflow.com/a/42456750
*/
static class SealedBoxNaCl{
static byte[] crypto_box_seal(byte[] clearText) throws GeneralSecurityException {
// create ephemeral keypair for sender
TweetNaclFast.Box.KeyPair ephkeypair = TweetNaclFast.Box.keyPair();
// create nonce
byte[] nonce = SealedBox.createNonce(ephkeypair.getPublicKey(), publicKey);
TweetNaclFast.Box box = new TweetNaclFast.Box(publicKey, ephkeypair.getSecretKey());
byte[] ciphertext = box.box(clearText, nonce);
if (ciphertext == null) throw new GeneralSecurityException("could not create box");

byte[] sealedbox = new byte[ciphertext.length + Util.PUBLIC_KEY_BYTES];
byte[] ephpubkey = ephkeypair.getPublicKey();

System.arraycopy(ephpubkey, 0, sealedbox, 0, Util.PUBLIC_KEY_BYTES);
System.arraycopy(ciphertext, 0, sealedbox, 32, ciphertext.length);

return sealedbox;
}

public static byte[] crypto_box_seal_open(byte[] c, byte[] pk, byte[] sk) throws GeneralSecurityException {
if (c.length < Util.PUBLIC_KEY_BYTES + Util.MAC_SIZE)
throw new IllegalArgumentException("Ciphertext too short");

byte[] pksender = Arrays.copyOfRange(c, 0, Util.PUBLIC_KEY_BYTES);
byte[] ciphertextwithmac = Arrays.copyOfRange(c, Util.PUBLIC_KEY_BYTES, c.length);
byte[] nonce = SealedBox.createNonce(pksender, pk);

TweetNaclFast.Box box = new TweetNaclFast.Box(pksender, sk);
byte[] cleartext = box.open(ciphertextwithmac, nonce);
if (cleartext == null) throw new GeneralSecurityException("could not open box");
return cleartext;
}
}
}

0 comments on commit 2b73ba0

Please sign in to comment.