Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add secret stream methods #111

Merged
merged 2 commits into from
Jul 5, 2018
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
61 changes: 61 additions & 0 deletions jni/sodium.i
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,21 @@
%typemap(freearg) crypto_auth_hmacsha512256_state *""


/*
crypto_secretstream_xchacha20poly1305_state
*/
%typemap(jni) crypto_secretstream_xchacha20poly1305_state *"jbyteArray"
%typemap(jtype) crypto_secretstream_xchacha20poly1305_state *"byte[]"
%typemap(jstype) crypto_secretstream_xchacha20poly1305_state *"byte[]"
%typemap(in) crypto_secretstream_xchacha20poly1305_state *{
$1 = (crypto_secretstream_xchacha20poly1305_state *) JCALL2(GetByteArrayElements, jenv, $input, 0);
}
%typemap(argout) crypto_secretstream_xchacha20poly1305_state *{
JCALL3(ReleaseByteArrayElements, jenv, $input, (jbyte *) $1, 0);
}
%typemap(javain) crypto_secretstream_xchacha20poly1305_state *"$javainput"
%typemap(freearg) crypto_secretstream_xchacha20poly1305_state *""


/* *****************************************************************************

Expand Down Expand Up @@ -1375,3 +1390,49 @@ int crypto_stream_xsalsa20_xor_ic(unsigned char *c,
const unsigned char *n,
uint64_t ic,
const unsigned char *k);

/*
Secret Stream Xchacha20 Poly1305
*/

size_t crypto_secretstream_xchacha20poly1305_keybytes(void);
size_t crypto_secretstream_xchacha20poly1305_headerbytes(void);
size_t crypto_secretstream_xchacha20poly1305_abytes(void);
size_t crypto_secretstream_xchacha20poly1305_statebytes(void);

size_t crypto_secretstream_xchacha20poly1305_tag_message(void);
size_t crypto_secretstream_xchacha20poly1305_tag_push(void);
size_t crypto_secretstream_xchacha20poly1305_tag_rekey(void);
size_t crypto_secretstream_xchacha20poly1305_tag_final(void);

size_t crypto_secretstream_xchacha20poly1305_messagebytes_max(void);

void crypto_secretstream_xchacha20poly1305_keygen(unsigned char *k);

int crypto_secretstream_xchacha20poly1305_init_push(crypto_secretstream_xchacha20poly1305_state *state,
unsigned char *header,
const unsigned char *k);

int crypto_secretstream_xchacha20poly1305_push(crypto_secretstream_xchacha20poly1305_state *state,
unsigned char *c,
unsigned long long *clen_p,
const unsigned char *m,
unsigned long long mlen,
const unsigned char *ad,
unsigned long long adlen,
unsigned char tag);

int crypto_secretstream_xchacha20poly1305_init_pull(crypto_secretstream_xchacha20poly1305_state *state,
const unsigned char *header,
const unsigned char *k);

int crypto_secretstream_xchacha20poly1305_pull(crypto_secretstream_xchacha20poly1305_state *state,
unsigned char *m,
unsigned long long *mlen_p,
unsigned char *tag_p,
const unsigned char *c,
unsigned long long clen,
const unsigned char *ad,
unsigned long long adlen);

void crypto_secretstream_xchacha20poly1305_rekey(crypto_secretstream_xchacha20poly1305_state *state);
60 changes: 60 additions & 0 deletions src/main/java/org/libsodium/jni/Sodium.java
Original file line number Diff line number Diff line change
Expand Up @@ -1081,4 +1081,64 @@ public static int crypto_stream_xsalsa20_xor_ic(byte[] c, byte[] m, int mlen, by
return SodiumJNI.crypto_stream_xsalsa20_xor_ic(c, m, mlen, n, ic, k);
}

public static int crypto_secretstream_xchacha20poly1305_keybytes() {
return SodiumJNI.crypto_secretstream_xchacha20poly1305_keybytes();
}

public static int crypto_secretstream_xchacha20poly1305_headerbytes() {
return SodiumJNI.crypto_secretstream_xchacha20poly1305_headerbytes();
}

public static int crypto_secretstream_xchacha20poly1305_abytes() {
return SodiumJNI.crypto_secretstream_xchacha20poly1305_abytes();
}

public static int crypto_secretstream_xchacha20poly1305_statebytes() {
return SodiumJNI.crypto_secretstream_xchacha20poly1305_statebytes();
}

public static int crypto_secretstream_xchacha20poly1305_tag_message() {
return SodiumJNI.crypto_secretstream_xchacha20poly1305_tag_message();
}

public static int crypto_secretstream_xchacha20poly1305_tag_push() {
return SodiumJNI.crypto_secretstream_xchacha20poly1305_tag_push();
}

public static int crypto_secretstream_xchacha20poly1305_tag_rekey() {
return SodiumJNI.crypto_secretstream_xchacha20poly1305_tag_rekey();
}

public static int crypto_secretstream_xchacha20poly1305_tag_final() {
return SodiumJNI.crypto_secretstream_xchacha20poly1305_tag_final();
}

public static int crypto_secretstream_xchacha20poly1305_messagebytes_max() {
return SodiumJNI.crypto_secretstream_xchacha20poly1305_messagebytes_max();
}

public static void crypto_secretstream_xchacha20poly1305_keygen(byte[] k) {
SodiumJNI.crypto_secretstream_xchacha20poly1305_keygen(k);
}

public static int crypto_secretstream_xchacha20poly1305_init_push(byte[] state, byte[] header, byte[] k) {
return SodiumJNI.crypto_secretstream_xchacha20poly1305_init_push(state, header, k);
}

public static int crypto_secretstream_xchacha20poly1305_push(byte[] state, byte[] c, int[] clen_p, byte[] m, int mlen, byte[] ad, int adlen, short tag) {
return SodiumJNI.crypto_secretstream_xchacha20poly1305_push(state, c, clen_p, m, mlen, ad, adlen, tag);
}

public static int crypto_secretstream_xchacha20poly1305_init_pull(byte[] state, byte[] header, byte[] k) {
return SodiumJNI.crypto_secretstream_xchacha20poly1305_init_pull(state, header, k);
}

public static int crypto_secretstream_xchacha20poly1305_pull(byte[] state, byte[] m, int[] mlen_p, byte[] tag_p, byte[] c, int clen, byte[] ad, int adlen) {
return SodiumJNI.crypto_secretstream_xchacha20poly1305_pull(state, m, mlen_p, tag_p, c, clen, ad, adlen);
}

public static void crypto_secretstream_xchacha20poly1305_rekey(byte[] state) {
SodiumJNI.crypto_secretstream_xchacha20poly1305_rekey(state);
}

}
15 changes: 15 additions & 0 deletions src/main/java/org/libsodium/jni/SodiumJNI.java
Original file line number Diff line number Diff line change
Expand Up @@ -277,4 +277,19 @@ public class SodiumJNI {
public final static native int crypto_stream_xsalsa20_noncebytes();
public final static native int crypto_stream_xsalsa20_xor(byte[] jarg1, byte[] jarg2, int jarg3, byte[] jarg4, byte[] jarg5);
public final static native int crypto_stream_xsalsa20_xor_ic(byte[] jarg1, byte[] jarg2, int jarg3, byte[] jarg4, int jarg5, byte[] jarg6);
public final static native int crypto_secretstream_xchacha20poly1305_keybytes();
public final static native int crypto_secretstream_xchacha20poly1305_headerbytes();
public final static native int crypto_secretstream_xchacha20poly1305_abytes();
public final static native int crypto_secretstream_xchacha20poly1305_statebytes();
public final static native int crypto_secretstream_xchacha20poly1305_tag_message();
public final static native int crypto_secretstream_xchacha20poly1305_tag_push();
public final static native int crypto_secretstream_xchacha20poly1305_tag_rekey();
public final static native int crypto_secretstream_xchacha20poly1305_tag_final();
public final static native int crypto_secretstream_xchacha20poly1305_messagebytes_max();
public final static native void crypto_secretstream_xchacha20poly1305_keygen(byte[] jarg1);
public final static native int crypto_secretstream_xchacha20poly1305_init_push(byte[] jarg1, byte[] jarg2, byte[] jarg3);
public final static native int crypto_secretstream_xchacha20poly1305_push(byte[] jarg1, byte[] jarg2, int[] jarg3, byte[] jarg4, int jarg5, byte[] jarg6, int jarg7, short jarg8);
public final static native int crypto_secretstream_xchacha20poly1305_init_pull(byte[] jarg1, byte[] jarg2, byte[] jarg3);
public final static native int crypto_secretstream_xchacha20poly1305_pull(byte[] jarg1, byte[] jarg2, int[] jarg3, byte[] jarg4, byte[] jarg5, int jarg6, byte[] jarg7, int jarg8);
public final static native void crypto_secretstream_xchacha20poly1305_rekey(byte[] jarg1);
}
82 changes: 82 additions & 0 deletions src/test/java/org/libsodium/jni/crypto/SecretStreamTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package org.libsodium.jni.crypto;

import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.fail;

import org.libsodium.jni.Sodium;
import org.libsodium.jni.encoders.Hex;

public class SecretStreamTest {
public static final String message1 = "Arbitrary data to encrypt";
public static final String message2 = "split into";
public static final String message3 = "three messages";
public static final String cipherText1 = "e9d5b0eceb20feda8af55547b0d3d8aa32b349cfe1c9e97d4220243691aea56a6281fced9c37bc57cc64";
public static final String cipherText2 = "24d51ef9c941c8cd7af13bc7260cdb0b4074a5d8da006151610a0a";
public static final String cipherText3 = "7d6180002f6d0248512fcb048e0d64baf536c994255af0cf7ae493e88f1d6d";
public static final String testKey = "6ad964e0e2cb155e662521242ef50023b1b03cf4736c7f1e2544aa5aa90c21ad";
public static final String testHeader = "05a5f60c257d6e004f656d72d764e150da0cc6239e63c444";
public static final String testState = "e0644ca907a613c71fe0399b17984d8e2868f4fcda4f223adcb662cd6adc8d9001000000da0cc6239e63c4440000000000000000";

@Test
public void testEncryption() {
Hex hex = new Hex();

byte[] state = hex.decode(testState);
byte[] ad = new byte[1];
int[] clen = new int[1];

byte[] c1 = new byte[25 + 17];
byte[] c2 = new byte[10 + 17];
byte[] c3 = new byte[14 + 17];

Sodium.crypto_secretstream_xchacha20poly1305_push(state, c1, clen, message1.getBytes(), 25, ad, 0, (short)0);
assertEquals(hex.encode(c1), cipherText1);

Sodium.crypto_secretstream_xchacha20poly1305_push(state, c2, clen, message2.getBytes(), 10, ad, 0, (short)0);
assertEquals(hex.encode(c2), cipherText2);

Sodium.crypto_secretstream_xchacha20poly1305_push(state, c3, clen, message3.getBytes(), 14, ad, 0, (short)3);
assertEquals(hex.encode(c3), cipherText3);
}

@Test
public void testDecryption() {
Hex hex = new Hex();

byte[] state = new byte[52];
byte[] key = hex.decode(testKey);
byte[] header = hex.decode(testHeader);
byte[] ad = new byte[1];
int[] mlen = new int[1];
byte[] tag = new byte[1];

byte[] c1 = hex.decode(cipherText1);
byte[] c2 = hex.decode(cipherText2);
byte[] c3 = hex.decode(cipherText3);

byte[] m1 = new byte[25];
byte[] m2 = new byte[10];
byte[] m3 = new byte[14];

if (Sodium.crypto_secretstream_xchacha20poly1305_init_pull(state, header, key) != 0) {
fail("Should return 0. Header is invalid.");
}

if (Sodium.crypto_secretstream_xchacha20poly1305_pull(state, m1, mlen, tag, c1, 25 + 17, ad, 0) != 0) {
fail("Should return 0. Corrupted cipherText.");
}
assertArrayEquals(m1, message1.getBytes());

if (Sodium.crypto_secretstream_xchacha20poly1305_pull(state, m2, mlen, tag, c2, 10 + 17, ad, 0) != 0) {
fail("Should return 0. Corrupted cipherText.");
}
assertArrayEquals(m2, message2.getBytes());

if (Sodium.crypto_secretstream_xchacha20poly1305_pull(state, m3, mlen, tag, c3, 14 + 17, ad, 0) != 0) {
fail("Should return 0. Corrupted cipherText.");
}
assertArrayEquals(m3, message3.getBytes());
}
}