pax_global_header00006660000000000000000000000064132505437460014523gustar00rootroot0000000000000052 comment=c6f71547d740ce1a94afd6925897b3c6b01ff649 jnacl-1.0/000077500000000000000000000000001325054374600124525ustar00rootroot00000000000000jnacl-1.0/.gitignore000066400000000000000000000001761325054374600144460ustar00rootroot00000000000000# Created by .gitignore support plugin (hsz.mobi) *.iml .idea/ target # Eclipse project files .classpath .project .settings/*jnacl-1.0/LICENSE000066400000000000000000000024231325054374600134600ustar00rootroot00000000000000Copyright (c) 2011, Neil Alexander T. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. jnacl-1.0/README.md000066400000000000000000000004301325054374600137260ustar00rootroot00000000000000jnacl ===== Pure Java implementation of the [NaCl: Networking and Cryptography library](http://nacl.cr.yp.to/) Supports the following crypto primitives: * curve25519xsalsa20poly1305 License ------- [The BSD 2-Clause License](http://opensource.org/licenses/bsd-license.php) jnacl-1.0/pom.xml000066400000000000000000000147521325054374600140000ustar00rootroot00000000000000 4.0.0 com.neilalexander jnacl 1.0 jar ${project.groupId}:${project.artifactId} Pure Java implementation of NaCl: Networking and Cryptography library. https://github.com/neilalexander/jnacl git@github.com:neilalexander/jnacl.git scm:git:git@github.com:neilalexander/jnacl.git scm:git:git@github.com:neilalexander/jnacl.git HEAD The BSD 2-Clause License http://opensource.org/licenses/bsd-license.php Neil Alexander https://github.com/neilalexander Martin W. Kirst maki@bitkings.de https://github.com/nitram509 UTF-8 ${project.build.outputDirectory}/META-INF/MANIFEST.MF ossrh https://oss.sonatype.org/content/repositories/snapshots ossrh https://oss.sonatype.org/service/local/staging/deploy/maven2/ org.testng testng 6.13.1 test org.easytesting fest-assert 1.4 test org.apache.maven.plugins maven-compiler-plugin 3.7.0 1.8 1.8 org.apache.maven.plugins maven-jar-plugin 3.0.2 ${manifest-file} biz.aQute.bnd bnd-maven-plugin 3.5.0 ${manifest-file} bnd-process org.apache.maven.plugins maven-source-plugin 3.0.1 attach-sources jar ${manifest-file} org.apache.maven.plugins maven-javadoc-plugin 3.0.0 ${manifest-file} attach-javadocs jar org.apache.maven.plugins maven-release-plugin 2.5.3 v@{project.version} ${manifest-file} doclint-java8-disable [1.8,) org.apache.maven.plugins maven-javadoc-plugin 2.9.1 -Xdoclint:none ${manifest-file} attach-javadocs jar release-sign-artifacts performRelease true org.apache.maven.plugins maven-gpg-plugin 1.6 sign-artifacts verify sign jnacl-1.0/src/000077500000000000000000000000001325054374600132415ustar00rootroot00000000000000jnacl-1.0/src/main/000077500000000000000000000000001325054374600141655ustar00rootroot00000000000000jnacl-1.0/src/main/java/000077500000000000000000000000001325054374600151065ustar00rootroot00000000000000jnacl-1.0/src/main/java/com/000077500000000000000000000000001325054374600156645ustar00rootroot00000000000000jnacl-1.0/src/main/java/com/neilalexander/000077500000000000000000000000001325054374600204775ustar00rootroot00000000000000jnacl-1.0/src/main/java/com/neilalexander/jnacl/000077500000000000000000000000001325054374600215665ustar00rootroot00000000000000jnacl-1.0/src/main/java/com/neilalexander/jnacl/NaCl.java000066400000000000000000000101051325054374600232430ustar00rootroot00000000000000// // Copyright (c) 2011, Neil Alexander T. // All rights reserved. // // Redistribution and use in source and binary forms, with // or without modification, are permitted provided that the following // conditions are met: // // - Redistributions of source code must retain the above copyright notice, // this list of conditions and the following disclaimer. // - Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. // package com.neilalexander.jnacl; import com.neilalexander.jnacl.crypto.curve25519xsalsa20poly1305; import java.util.Formatter; public class NaCl { static final int crypto_secretbox_KEYBYTES = 32; static final int crypto_secretbox_NONCEBYTES = 24; static final int crypto_secretbox_ZEROBYTES = 32; static final int crypto_secretbox_BOXZEROBYTES = 16; static final int crypto_secretbox_BEFORENMBYTES = 32; private byte[] precomputed = new byte[crypto_secretbox_BEFORENMBYTES]; public NaCl(byte[] privatekey, byte[] publickey) throws Exception { if (privatekey.length < crypto_secretbox_KEYBYTES) throw new Exception("Private key too short"); if (publickey.length < crypto_secretbox_KEYBYTES) throw new Exception("Public key too short"); curve25519xsalsa20poly1305.crypto_box_beforenm(this.precomputed, publickey, privatekey); } public NaCl(String privatekey, String publickey) throws Exception { this(getBinary(privatekey), getBinary(publickey)); } public byte[] encrypt(byte[] input, byte[] nonce) { return encrypt(input, input.length, nonce); } public byte[] encrypt(byte[] input, int inputlength, byte[] nonce) { byte[] paddedinput = new byte[inputlength + crypto_secretbox_ZEROBYTES]; byte[] output = new byte[inputlength + crypto_secretbox_ZEROBYTES]; System.arraycopy(input, 0, paddedinput, crypto_secretbox_ZEROBYTES, inputlength); curve25519xsalsa20poly1305.crypto_box_afternm(output, paddedinput, paddedinput.length, nonce, this.precomputed); return output; } public byte[] decrypt(byte[] input, byte[] nonce) { return decrypt(input, input.length, nonce); } public byte[] decrypt(byte[] input, int inputlength, byte[] nonce) { byte[] paddedoutput = new byte[inputlength]; byte[] output = new byte[inputlength - crypto_secretbox_ZEROBYTES]; curve25519xsalsa20poly1305.crypto_box_open_afternm(paddedoutput, input, inputlength, nonce, this.precomputed); System.arraycopy(paddedoutput, crypto_secretbox_ZEROBYTES, output, 0, paddedoutput.length - crypto_secretbox_ZEROBYTES); return output; } public static byte[] getBinary(String s) { int len = s.length(); byte[] data = new byte[len / 2]; for (int i = 0; i < len; i += 2) data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character.digit(s.charAt(i + 1), 16)); return data; } public static String asHex(byte[] buf) { Formatter formatter = new Formatter(); for (byte b : buf) formatter.format("%02x", b); return formatter.toString(); } public static String asHex(int[] buf) { Formatter formatter = new Formatter(); for (int b : buf) formatter.format("%02x", b); return formatter.toString(); } } jnacl-1.0/src/main/java/com/neilalexander/jnacl/crypto/000077500000000000000000000000001325054374600231065ustar00rootroot00000000000000jnacl-1.0/src/main/java/com/neilalexander/jnacl/crypto/curve25519.java000066400000000000000000000226761325054374600255200ustar00rootroot00000000000000// // Copyright (c) 2011, Neil Alexander T. // All rights reserved. // // Redistribution and use in source and binary forms, with // or without modification, are permitted provided that the following // conditions are met: // // - Redistributions of source code must retain the above copyright notice, // this list of conditions and the following disclaimer. // - Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. // package com.neilalexander.jnacl.crypto; public class curve25519 { final int CRYPTO_BYTES = 32; final int CRYPTO_SCALARBYTES = 32; static byte[] basev = { 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; static int[] minusp = { 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128 }; public static int crypto_scalarmult_base(byte[] q, byte[] n) { byte[] basevp = basev; return crypto_scalarmult(q, n, basevp); } static void add(int[] outv, int outvoffset, int[] a, int aoffset, int[] b, int boffset) { int u = 0; for (int j = 0; j < 31; ++j) { u += a[aoffset + j] + b[boffset + j]; outv[outvoffset + j] = u & 255; u >>>= 8; } u += a[aoffset + 31] + b[boffset + 31]; outv[outvoffset + 31] = u; } static void sub(int[] outv, int outvoffset, int[] a, int aoffset, int[] b, int boffset) { int u = 218; for (int j = 0; j < 31; ++j) { u += a[aoffset + j] + 65280 - b[boffset + j]; outv[outvoffset + j] = u & 255; u >>>= 8; } u += a[aoffset + 31] - b[boffset + 31]; outv[outvoffset + 31] = u; } static void squeeze(int[] a, int aoffset) { int u = 0; for (int j = 0; j < 31; ++j) { u += a[aoffset + j]; a[aoffset + j] = u & 255; u >>>= 8; } u += a[aoffset + 31]; a[aoffset + 31] = u & 127; u = 19 * (u >>> 7); for (int j = 0; j < 31; ++j) { u += a[aoffset + j]; a[aoffset + j] = u & 255; u >>>= 8; } u += a[aoffset + 31]; a[aoffset + 31] = u; } static void freeze(int[] a, int aoffset) { int[] aorig = new int[32]; for (int j = 0; j < 32; ++j) aorig[j] = a[aoffset + j]; int[] minuspp = minusp; add(a, 0, a, 0, minuspp, 0); int negative = (int) (-((a[aoffset + 31] >>> 7) & 1)); for (int j = 0; j < 32; ++j) a[aoffset + j] ^= negative & (aorig[j] ^ a[aoffset + j]); } static void mult(int[] outv, int outvoffset, int[] a, int aoffset, int[] b, int boffset) { int j; for (int i = 0; i < 32; ++i) { int u = 0; for (j = 0; j <= i; ++j) u += a[aoffset + j] * b[boffset + i - j]; for (j = i + 1; j < 32; ++j) u += 38 * a[aoffset + j] * b[boffset + i + 32 - j]; outv[outvoffset + i] = u; } squeeze(outv, outvoffset); } static void mult121665(int[] outv, int[] a) { int j; int u = 0; for (j = 0; j < 31; ++j) { u += 121665 * a[j]; outv[j] = u & 255; u >>>= 8; } u += 121665 * a[31]; outv[31] = u & 127; u = 19 * (u >>> 7); for (j = 0; j < 31; ++j) { u += outv[j]; outv[j] = u & 255; u >>>= 8; } u += outv[j]; outv[j] = u; } static void square(int[] outv, int outvoffset, int[] a, int aoffset) { int j; for (int i = 0; i < 32; ++i) { int u = 0; for (j = 0; j < i - j; ++j) u += a[aoffset + j] * a[aoffset + i - j]; for (j = i + 1; j < i + 32 - j; ++j) u += 38 * a[aoffset + j] * a[aoffset + i + 32 - j]; u *= 2; if ((i & 1) == 0) { u += a[aoffset + i / 2] * a[aoffset + i / 2]; u += 38 * a[aoffset + i / 2 + 16] * a[aoffset + i / 2 + 16]; } outv[outvoffset + i] = u; } squeeze(outv, outvoffset); } static void select(int[] p, int[] q, int[] r, int[] s, int b) { int bminus1 = b - 1; for (int j = 0; j < 64; ++j) { int t = bminus1 & (r[j] ^ s[j]); p[j] = s[j] ^ t; q[j] = r[j] ^ t; } } static void mainloop(int[] work, byte[] e) { int[] xzm1 = new int[64]; int[] xzm = new int[64]; int[] xzmb = new int[64]; int[] xzm1b = new int[64]; int[] xznb = new int[64]; int[] xzn1b = new int[64]; int[] a0 = new int[64]; int[] a1 = new int[64]; int[] b0 = new int[64]; int[] b1 = new int[64]; int[] c1 = new int[64]; int[] r = new int[32]; int[] s = new int[32]; int[] t = new int[32]; int[] u = new int[32]; for (int j = 0; j < 32; ++j) xzm1[j] = work[j]; xzm1[32] = 1; for (int j = 33; j < 64; ++j) xzm1[j] = 0; xzm[0] = 1; for (int j = 1; j < 64; ++j) xzm[j] = 0; for (int pos = 254; pos >= 0; --pos) { int b = ((int) ((e[pos / 8] & 0xFF) >>> (pos & 7))); b &= 1; select(xzmb, xzm1b, xzm, xzm1, b); add(a0, 0, xzmb, 0, xzmb, 32); sub(a0, 32, xzmb, 0, xzmb, 32); add(a1, 0, xzm1b, 0, xzm1b, 32); sub(a1, 32, xzm1b, 0, xzm1b, 32); square(b0, 0, a0, 0); square(b0, 32, a0, 32); mult(b1, 0, a1, 0, a0, 32); mult(b1, 32, a1, 32, a0, 0); add(c1, 0, b1, 0, b1, 32); sub(c1, 32, b1, 0, b1, 32); square(r, 0, c1, 32); sub(s, 0, b0, 0, b0, 32); mult121665(t, s); add(u, 0, t, 0, b0, 0); mult(xznb, 0, b0, 0, b0, 32); mult(xznb, 32, s, 0, u, 0); square(xzn1b, 0, c1, 0); mult(xzn1b, 32, r, 0, work, 0); select(xzm, xzm1, xznb, xzn1b, b); } for (int j = 0; j < 64; ++j) work[j] = xzm[j]; } static void recip(int[] outv, int outvoffset, int[] z, int zoffset) { int[] z2 = new int[32]; int[] z9 = new int[32]; int[] z11 = new int[32]; int[] z2_5_0 = new int[32]; int[] z2_10_0 = new int[32]; int[] z2_20_0 = new int[32]; int[] z2_50_0 = new int[32]; int[] z2_100_0 = new int[32]; int[] t0 = new int[32]; int[] t1 = new int[32]; /* 2 */ square(z2, 0, z, zoffset); /* 4 */ square(t1, 0, z2, 0); /* 8 */ square(t0, 0, t1, 0); /* 9 */ mult(z9, 0, t0, 0, z, zoffset); /* 11 */ mult(z11, 0, z9, 0, z2, 0); /* 22 */ square(t0, 0, z11, 0); /* 2^5 - 2^0 = 31 */ mult(z2_5_0, 0, t0, 0, z9, 0); /* 2^6 - 2^1 */ square(t0, 0, z2_5_0, 0); /* 2^7 - 2^2 */ square(t1, 0, t0, 0); /* 2^8 - 2^3 */ square(t0, 0, t1, 0); /* 2^9 - 2^4 */ square(t1, 0, t0, 0); /* 2^10 - 2^5 */ square(t0, 0, t1, 0); /* 2^10 - 2^0 */ mult(z2_10_0, 0, t0, 0, z2_5_0, 0); /* 2^11 - 2^1 */ square(t0, 0, z2_10_0, 0); /* 2^12 - 2^2 */ square(t1, 0, t0, 0); /* 2^20 - 2^10 */ for (int i = 2; i < 10; i += 2) { square(t0, 0, t1, 0); square(t1, 0, t0, 0); } /* 2^20 - 2^0 */ mult(z2_20_0, 0, t1, 0, z2_10_0, 0); /* 2^21 - 2^1 */ square(t0, 0, z2_20_0, 0); /* 2^22 - 2^2 */ square(t1, 0, t0, 0); /* 2^40 - 2^20 */ for (int i = 2; i < 20; i += 2) { square(t0, 0, t1, 0); square(t1, 0, t0, 0); } /* 2^40 - 2^0 */ mult(t0, 0, t1, 0, z2_20_0, 0); /* 2^41 - 2^1 */ square(t1, 0, t0, 0); /* 2^42 - 2^2 */ square(t0, 0, t1, 0); /* 2^50 - 2^10 */ for (int i = 2; i < 10; i += 2) { square(t1, 0, t0, 0); square(t0, 0, t1, 0); } /* 2^50 - 2^0 */ mult(z2_50_0, 0, t0, 0, z2_10_0, 0); /* 2^51 - 2^1 */ square(t0, 0, z2_50_0, 0); /* 2^52 - 2^2 */ square(t1, 0, t0, 0); /* 2^100 - 2^50 */ for (int i = 2; i < 50; i += 2) { square(t0, 0, t1, 0); square(t1, 0, t0, 0); } /* 2^100 - 2^0 */ mult(z2_100_0, 0, t1, 0, z2_50_0, 0); /* 2^101 - 2^1 */ square(t1, 0, z2_100_0, 0); /* 2^102 - 2^2 */ square(t0, 0, t1, 0); /* 2^200 - 2^100 */ for (int i = 2; i < 100; i += 2) { square(t1, 0, t0, 0); square(t0, 0, t1, 0); } /* 2^200 - 2^0 */ mult(t1, 0, t0, 0, z2_100_0, 0); /* 2^201 - 2^1 */ square(t0, 0, t1, 0); /* 2^202 - 2^2 */ square(t1, 0, t0, 0); /* 2^250 - 2^50 */ for (int i = 2; i < 50; i += 2) { square(t0, 0, t1, 0); square(t1, 0, t0, 0); } /* 2^250 - 2^0 */ mult(t0, 0, t1, 0, z2_50_0, 0); /* 2^251 - 2^1 */ square(t1, 0, t0, 0); /* 2^252 - 2^2 */ square(t0, 0, t1, 0); /* 2^253 - 2^3 */ square(t1, 0, t0, 0); /* 2^254 - 2^4 */ square(t0, 0, t1, 0); /* 2^255 - 2^5 */ square(t1, 0, t0, 0); /* 2^255 - 21 */ mult(outv, outvoffset, t1, 0, z11, 0); } public static int crypto_scalarmult(byte[] q, byte[] n, byte[] p) { int[] work = new int[96]; byte[] e = new byte[32]; for (int i = 0; i < 32; ++i) e[i] = n[i]; e[0] &= 248; e[31] &= 127; e[31] |= 64; for (int i = 0; i < 32; ++i) work[i] = p[i] & 0xFF; mainloop(work, e); recip(work, 32, work, 32); mult(work, 64, work, 0, work, 32); freeze(work, 64); for (int i = 0; i < 32; ++i) q[i] = (byte) work[64 + i]; return 0; } } jnacl-1.0/src/main/java/com/neilalexander/jnacl/crypto/curve25519xsalsa20poly1305.java000066400000000000000000000074041325054374600303030ustar00rootroot00000000000000// // Copyright (c) 2011, Neil Alexander T. // All rights reserved. // // Redistribution and use in source and binary forms, with // or without modification, are permitted provided that the following // conditions are met: // // - Redistributions of source code must retain the above copyright notice, // this list of conditions and the following disclaimer. // - Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. // package com.neilalexander.jnacl.crypto; import java.security.SecureRandom; public class curve25519xsalsa20poly1305 { public static final int crypto_secretbox_PUBLICKEYBYTES = 32; public static final int crypto_secretbox_SECRETKEYBYTES = 32; public static final int crypto_secretbox_BEFORENMBYTES = 32; public static final int crypto_secretbox_NONCEBYTES = 24; public static final int crypto_secretbox_ZEROBYTES = 32; public static final int crypto_secretbox_BOXZEROBYTES = 16; public static int crypto_box_getpublickey(byte[] pk, byte[] sk) { return curve25519.crypto_scalarmult_base(pk, sk); } public static int crypto_box_keypair(byte[] pk, byte[] sk) { SecureRandom rng = new SecureRandom(); rng.nextBytes(sk); return curve25519.crypto_scalarmult_base(pk, sk); } public static int crypto_box_afternm(byte[] c, byte[] m, long mlen, byte[] n, byte[] k) { return xsalsa20poly1305.crypto_secretbox(c, m, mlen, n, k); } public static int crypto_box_beforenm(byte[] k, byte[] pk, byte[] sk) { byte[] sp = new byte[32], sigmap = xsalsa20.sigma; curve25519.crypto_scalarmult(sp, sk, pk); return hsalsa20.crypto_core(k, null, sp, sigmap); } public static int crypto_box(byte[] c, byte[] m, long mlen, byte[] n, byte[] pk, byte[] sk) { byte[] kp = new byte[crypto_secretbox_BEFORENMBYTES]; crypto_box_beforenm(kp, pk, sk); return crypto_box_afternm(c, m, mlen, n, kp); } public static int crypto_box_open(byte[] m, byte[] c, long clen, byte[] n, byte[] pk, byte[] sk) { byte[] kp = new byte[crypto_secretbox_BEFORENMBYTES]; crypto_box_beforenm(kp, pk, sk); return crypto_box_open_afternm(m, c, clen, n, kp); } public static int crypto_box_open_afternm(byte[] m, byte[] c, long clen, byte[] n, byte[] k) { return xsalsa20poly1305.crypto_secretbox_open(m, c, clen, n, k); } public static int crypto_box_afternm(byte[] c, byte[] m, byte[] n, byte[] k) { return crypto_box_afternm(c, m, (long)m.length, n, k); } public static int crypto_box_open_afternm(byte[] m, byte[] c, byte[] n, byte[] k) { return crypto_box_open_afternm(m, c, (long) c.length, n, k); } public static int crypto_box(byte[] c, byte[] m, byte[] n, byte[] pk, byte[] sk) { return crypto_box(c, m, (long) m.length, n, pk, sk); } public static int crypto_box_open(byte[] m, byte[] c, byte[] n, byte[] pk, byte[] sk) { return crypto_box_open(m, c, (long) c.length, n, pk, sk); } } jnacl-1.0/src/main/java/com/neilalexander/jnacl/crypto/hsalsa20.java000066400000000000000000000113071325054374600253700ustar00rootroot00000000000000// // Copyright (c) 2011, Neil Alexander T. // All rights reserved. // // Redistribution and use in source and binary forms, with // or without modification, are permitted provided that the following // conditions are met: // // - Redistributions of source code must retain the above copyright notice, // this list of conditions and the following disclaimer. // - Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. // package com.neilalexander.jnacl.crypto; public class hsalsa20 { static final int ROUNDS = 20; static int rotate(int u, int c) { return (u << c) | (u >>> (32 - c)); } static int load_littleendian(byte[] x, int offset) { return ((int)(x[offset])&0xff) | ((((int)(x[offset + 1])&0xff)) << 8) | ((((int)(x[offset + 2])&0xff)) << 16) | ((((int)(x[offset + 3])&0xff)) << 24); } static void store_littleendian(byte[] x, int offset, int u) { x[offset] = (byte) u; u >>>= 8; x[offset + 1] = (byte) u; u >>>= 8; x[offset + 2] = (byte) u; u >>>= 8; x[offset + 3] = (byte) u; } public static int crypto_core(byte[] outv, byte[] inv, byte[] k, byte[] c) { int x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15; int j0, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, j15; int i; j0 = x0 = load_littleendian(c, 0); j1 = x1 = load_littleendian(k, 0); j2 = x2 = load_littleendian(k, 4); j3 = x3 = load_littleendian(k, 8); j4 = x4 = load_littleendian(k, 12); j5 = x5 = load_littleendian(c, 4); if (inv != null) { j6 = x6 = load_littleendian(inv, 0); j7 = x7 = load_littleendian(inv, 4); j8 = x8 = load_littleendian(inv, 8); j9 = x9 = load_littleendian(inv, 12); } else { j6 = x6 = j7 = x7 = j8 = x8 = j9 = x9 = 0; } j10 = x10 = load_littleendian(c, 8); j11 = x11 = load_littleendian(k, 16); j12 = x12 = load_littleendian(k, 20); j13 = x13 = load_littleendian(k, 24); j14 = x14 = load_littleendian(k, 28); j15 = x15 = load_littleendian(c, 12); for (i = ROUNDS; i > 0; i -= 2) { x4 ^= rotate(x0 + x12, 7); x8 ^= rotate(x4 + x0, 9); x12 ^= rotate(x8 + x4, 13); x0 ^= rotate(x12 + x8, 18); x9 ^= rotate(x5 + x1, 7); x13 ^= rotate(x9 + x5, 9); x1 ^= rotate(x13 + x9, 13); x5 ^= rotate(x1 + x13, 18); x14 ^= rotate(x10 + x6, 7); x2 ^= rotate(x14 + x10, 9); x6 ^= rotate(x2 + x14, 13); x10 ^= rotate(x6 + x2, 18); x3 ^= rotate(x15 + x11, 7); x7 ^= rotate(x3 + x15, 9); x11 ^= rotate(x7 + x3, 13); x15 ^= rotate(x11 + x7, 18); x1 ^= rotate(x0 + x3, 7); x2 ^= rotate(x1 + x0, 9); x3 ^= rotate(x2 + x1, 13); x0 ^= rotate(x3 + x2, 18); x6 ^= rotate(x5 + x4, 7); x7 ^= rotate(x6 + x5, 9); x4 ^= rotate(x7 + x6, 13); x5 ^= rotate(x4 + x7, 18); x11 ^= rotate(x10 + x9, 7); x8 ^= rotate(x11 + x10, 9); x9 ^= rotate(x8 + x11, 13); x10 ^= rotate(x9 + x8, 18); x12 ^= rotate(x15 + x14, 7); x13 ^= rotate(x12 + x15, 9); x14 ^= rotate(x13 + x12, 13); x15 ^= rotate(x14 + x13, 18); } x0 += j0; x1 += j1; x2 += j2; x3 += j3; x4 += j4; x5 += j5; x6 += j6; x7 += j7; x8 += j8; x9 += j9; x10 += j10; x11 += j11; x12 += j12; x13 += j13; x14 += j14; x15 += j15; x0 -= load_littleendian(c, 0); x5 -= load_littleendian(c, 4); x10 -= load_littleendian(c, 8); x15 -= load_littleendian(c, 12); if (inv != null) { x6 -= load_littleendian(inv, 0); x7 -= load_littleendian(inv, 4); x8 -= load_littleendian(inv, 8); x9 -= load_littleendian(inv, 12); } store_littleendian(outv, 0, x0); store_littleendian(outv, 4, x5); store_littleendian(outv, 8, x10); store_littleendian(outv, 12, x15); store_littleendian(outv, 16, x6); store_littleendian(outv, 20, x7); store_littleendian(outv, 24, x8); store_littleendian(outv, 28, x9); return 0; } } jnacl-1.0/src/main/java/com/neilalexander/jnacl/crypto/poly1305.java000066400000000000000000000076471325054374600252630ustar00rootroot00000000000000// // Copyright (c) 2011, Neil Alexander T. // All rights reserved. // // Redistribution and use in source and binary forms, with // or without modification, are permitted provided that the following // conditions are met: // // - Redistributions of source code must retain the above copyright notice, // this list of conditions and the following disclaimer. // - Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. // package com.neilalexander.jnacl.crypto; public class poly1305 { final int CRYPTO_BYTES = 16; final int CRYPTO_KEYBYTES = 32; static final int[] minusp = {5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 252}; public static int crypto_onetimeauth_verify(byte[] h, int hoffset, byte[] inv, int invoffset, long inlen, byte[] k) { byte[] correct = new byte[16]; crypto_onetimeauth(correct, 0, inv, invoffset, inlen, k); return verify_16.crypto_verify(h, hoffset, correct); } static void add(int[] h, int[] c) { int j; int u = 0; for (j = 0; j < 17; ++j) { u += h[j] + c[j]; h[j] = u & 255; u >>>= 8; } } static void squeeze(int[] h) { int u = 0; for (int j = 0; j < 16; ++j) { u += h[j]; h[j] = u & 255; u >>>= 8; } u += h[16]; h[16] = u & 3; u = 5 * (u >>> 2); for (int j = 0; j < 16; ++j) { u += h[j]; h[j] = u & 255; u >>>= 8; } u += h[16]; h[16] = u; } static void freeze(int[] h) { int[] horig = new int[17]; for (int j = 0; j < 17; ++j) horig[j] = h[j]; add(h, minusp); int negative = (int)(-(h[16] >>> 7)); for (int j = 0; j < 17; ++j) h[j] ^= negative & (horig[j] ^ h[j]); } static void mulmod(int[] h, int[] r) { int[] hr = new int[17]; for (int i = 0; i < 17; ++i) { int u = 0; for (int j = 0; j <= i; ++j) u += h[j] * r[i - j]; for (int j = i + 1; j < 17; ++j) u += 320 * h[j] * r[i + 17 - j]; hr[i] = u; } for (int i = 0; i < 17; ++i) h[i] = hr[i]; squeeze(h); } public static int crypto_onetimeauth(byte[] outv, int outvoffset, byte[] inv, int invoffset, long inlen, byte[] k) { int j; int[] r = new int[17]; int[] h = new int[17]; int[] c = new int[17]; r[0] = k[0] & 0xFF; r[1] = k[1] & 0xFF; r[2] = k[2] & 0xFF; r[3] = k[3] & 15; r[4] = k[4] & 252; r[5] = k[5] & 0xFF; r[6] = k[6] & 0xFF; r[7] = k[7] & 15; r[8] = k[8] & 252; r[9] = k[9] & 0xFF; r[10] = k[10] & 0xFF; r[11] = k[11] & 15; r[12] = k[12] & 252; r[13] = k[13] & 0xFF; r[14] = k[14] & 0xFF; r[15] = k[15] & 15; r[16] = 0; for (j = 0; j < 17; ++j) h[j] = 0; while (inlen > 0) { for (j = 0; j < 17; ++j) c[j] = 0; for (j = 0; (j < 16) && (j < inlen); ++j) c[j] = inv[invoffset + j]&0xff; c[j] = 1; invoffset += j; inlen -= j; add(h, c); mulmod(h, r); } freeze(h); for (j = 0; j < 16; ++j) c[j] = k[j + 16] & 0xFF; c[16] = 0; add(h, c); for (j = 0; j < 16; ++j) outv[j + outvoffset] = (byte)h[j]; return 0; } } jnacl-1.0/src/main/java/com/neilalexander/jnacl/crypto/salsa20.java000066400000000000000000000147301325054374600252230ustar00rootroot00000000000000// // Copyright (c) 2011, Neil Alexander T. // All rights reserved. // // Redistribution and use in source and binary forms, with // or without modification, are permitted provided that the following // conditions are met: // // - Redistributions of source code must retain the above copyright notice, // this list of conditions and the following disclaimer. // - Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. // package com.neilalexander.jnacl.crypto; public class salsa20 { final int crypto_core_salsa20_ref_OUTPUTBYTES = 64; final int crypto_core_salsa20_ref_INPUTBYTES = 16; final int crypto_core_salsa20_ref_KEYBYTES = 32; final int crypto_core_salsa20_ref_CONSTBYTES = 16; final int crypto_stream_salsa20_ref_KEYBYTES = 32; final int crypto_stream_salsa20_ref_NONCEBYTES = 8; final static int ROUNDS = 20; static long rotate(int u, int c) { return (u << c) | (u >>> (32 - c)); } static int load_littleendian(byte[] x, int offset) { return ((int)(x[offset])&0xff) | ((((int)(x[offset + 1])&0xff)) << 8) | ((((int)(x[offset + 2])&0xff)) << 16) | ((((int)(x[offset + 3])&0xff)) << 24); } static void store_littleendian(byte[] x, int offset, int u) { x[offset] = (byte) u; u >>>= 8; x[offset + 1] = (byte) u; u >>>= 8; x[offset + 2] = (byte) u; u >>>= 8; x[offset + 3] = (byte) u; } public static int crypto_core(byte[] outv, byte[] inv, byte[] k, byte[] c) { int x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15; int j0, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, j15; int i; j0 = x0 = load_littleendian(c, 0); j1 = x1 = load_littleendian(k, 0); j2 = x2 = load_littleendian(k, 4); j3 = x3 = load_littleendian(k, 8); j4 = x4 = load_littleendian(k, 12); j5 = x5 = load_littleendian(c, 4); j6 = x6 = load_littleendian(inv, 0); j7 = x7 = load_littleendian(inv, 4); j8 = x8 = load_littleendian(inv, 8); j9 = x9 = load_littleendian(inv, 12); j10 = x10 = load_littleendian(c, 8); j11 = x11 = load_littleendian(k, 16); j12 = x12 = load_littleendian(k, 20); j13 = x13 = load_littleendian(k, 24); j14 = x14 = load_littleendian(k, 28); j15 = x15 = load_littleendian(c, 12); for (i = ROUNDS; i > 0; i -= 2) { x4 ^= rotate(x0 + x12, 7); x8 ^= rotate(x4 + x0, 9); x12 ^= rotate(x8 + x4, 13); x0 ^= rotate(x12 + x8, 18); x9 ^= rotate(x5 + x1, 7); x13 ^= rotate(x9 + x5, 9); x1 ^= rotate(x13 + x9, 13); x5 ^= rotate(x1 + x13, 18); x14 ^= rotate(x10 + x6, 7); x2 ^= rotate(x14 + x10, 9); x6 ^= rotate(x2 + x14, 13); x10 ^= rotate(x6 + x2, 18); x3 ^= rotate(x15 + x11, 7); x7 ^= rotate(x3 + x15, 9); x11 ^= rotate(x7 + x3, 13); x15 ^= rotate(x11 + x7, 18); x1 ^= rotate(x0 + x3, 7); x2 ^= rotate(x1 + x0, 9); x3 ^= rotate(x2 + x1, 13); x0 ^= rotate(x3 + x2, 18); x6 ^= rotate(x5 + x4, 7); x7 ^= rotate(x6 + x5, 9); x4 ^= rotate(x7 + x6, 13); x5 ^= rotate(x4 + x7, 18); x11 ^= rotate(x10 + x9, 7); x8 ^= rotate(x11 + x10, 9); x9 ^= rotate(x8 + x11, 13); x10 ^= rotate(x9 + x8, 18); x12 ^= rotate(x15 + x14, 7); x13 ^= rotate(x12 + x15, 9); x14 ^= rotate(x13 + x12, 13); x15 ^= rotate(x14 + x13, 18); } x0 += j0; x1 += j1; x2 += j2; x3 += j3; x4 += j4; x5 += j5; x6 += j6; x7 += j7; x8 += j8; x9 += j9; x10 += j10; x11 += j11; x12 += j12; x13 += j13; x14 += j14; x15 += j15; store_littleendian(outv, 0, x0); store_littleendian(outv, 4, x1); store_littleendian(outv, 8, x2); store_littleendian(outv, 12, x3); store_littleendian(outv, 16, x4); store_littleendian(outv, 20, x5); store_littleendian(outv, 24, x6); store_littleendian(outv, 28, x7); store_littleendian(outv, 32, x8); store_littleendian(outv, 36, x9); store_littleendian(outv, 40, x10); store_littleendian(outv, 44, x11); store_littleendian(outv, 48, x12); store_littleendian(outv, 52, x13); store_littleendian(outv, 56, x14); store_littleendian(outv, 60, x15); return 0; } public static int crypto_stream(byte[] c, int clen, byte[] n, int noffset, byte[] k) { byte[] inv = new byte[16]; byte[] block = new byte[64]; int coffset = 0; if (clen == 0) return 0; for (int i = 0; i < 8; ++i) inv[i] = n[noffset + i]; for (int i = 8; i < 16; ++i) inv[i] = 0; while (clen >= 64) { salsa20.crypto_core(c, inv, k, xsalsa20.sigma); int u = 1; for (int i = 8; i < 16; ++i) { u += inv[i]&0xff; inv[i] = (byte) u; u >>>= 8; } clen -= 64; coffset += 64; } if (clen != 0) { salsa20.crypto_core(block, inv, k, xsalsa20.sigma); for (int i = 0; i < clen; ++i) c[coffset + i] = block[i]; } return 0; } public static int crypto_stream_xor(byte[] c, byte[] m, int mlen, byte[] n, int noffset, byte[] k) { byte[] inv = new byte[16]; byte[] block = new byte[64]; int coffset = 0; int moffset = 0; if (mlen == 0) return 0; for (int i = 0; i < 8; ++i) inv[i] = n[noffset + i]; for (int i = 8; i < 16; ++i) inv[i] = 0; while (mlen >= 64) { salsa20.crypto_core(block, inv, k, xsalsa20.sigma); for (int i = 0; i < 64; ++i) c[coffset + i] = (byte)(m[moffset + i] ^ block[i]); int u = 1; for (int i = 8; i < 16; ++i) { u += inv[i]&0xff; inv[i] = (byte) u; u >>>= 8; } mlen -= 64; coffset += 64; moffset += 64; } if (mlen != 0) { salsa20.crypto_core(block, inv, k, xsalsa20.sigma); for (int i = 0; i < mlen; ++i) c[coffset + i] = (byte)(m[moffset + i] ^ block[i]); } return 0; } } jnacl-1.0/src/main/java/com/neilalexander/jnacl/crypto/verify_16.java000066400000000000000000000033361325054374600255700ustar00rootroot00000000000000// // Copyright (c) 2011, Neil Alexander T. // All rights reserved. // // Redistribution and use in source and binary forms, with // or without modification, are permitted provided that the following // conditions are met: // // - Redistributions of source code must retain the above copyright notice, // this list of conditions and the following disclaimer. // - Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. // package com.neilalexander.jnacl.crypto; public class verify_16 { final int crypto_verify_16_ref_BYTES = 16; public static int crypto_verify(byte[] x, int xoffset, byte[] y) { int differentbits = 0; for (int i = 0; i < 15; i++) differentbits |= ((int)(x[xoffset + i] ^ y[i])) & 0xff; return (1 & (((int)differentbits - 1) >>> 8)) - 1; } } jnacl-1.0/src/main/java/com/neilalexander/jnacl/crypto/xsalsa20.java000066400000000000000000000043651325054374600254160ustar00rootroot00000000000000// // Copyright (c) 2011, Neil Alexander T. // All rights reserved. // // Redistribution and use in source and binary forms, with // or without modification, are permitted provided that the following // conditions are met: // // - Redistributions of source code must retain the above copyright notice, // this list of conditions and the following disclaimer. // - Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. // package com.neilalexander.jnacl.crypto; public class xsalsa20 { final int crypto_stream_xsalsa20_ref_KEYBYTES = 32; final int crypto_stream_xsalsa20_ref_NONCEBYTES = 24; public final static byte[] sigma = {(byte) 'e', (byte) 'x', (byte) 'p', (byte) 'a', (byte) 'n', (byte) 'd', (byte) ' ', (byte) '3', (byte) '2', (byte) '-', (byte) 'b', (byte) 'y', (byte) 't', (byte) 'e', (byte) ' ', (byte) 'k'}; public static int crypto_stream(byte[] c, int clen, byte[] n, byte[] k) { byte[] subkey = new byte[32]; hsalsa20.crypto_core(subkey, n, k, sigma); return salsa20.crypto_stream(c, clen, n, 16, subkey); } public static int crypto_stream_xor(byte[] c, byte[] m, long mlen, byte[] n, byte[] k) { byte[] subkey = new byte[32]; hsalsa20.crypto_core(subkey, n, k, sigma); return salsa20.crypto_stream_xor(c, m, (int) mlen, n, 16, subkey); } } jnacl-1.0/src/main/java/com/neilalexander/jnacl/crypto/xsalsa20poly1305.java000066400000000000000000000045041325054374600266260ustar00rootroot00000000000000// // Copyright (c) 2011, Neil Alexander T. // All rights reserved. // // Redistribution and use in source and binary forms, with // or without modification, are permitted provided that the following // conditions are met: // // - Redistributions of source code must retain the above copyright notice, // this list of conditions and the following disclaimer. // - Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. // package com.neilalexander.jnacl.crypto; public class xsalsa20poly1305 { final int crypto_secretbox_KEYBYTES = 32; final int crypto_secretbox_NONCEBYTES = 24; final int crypto_secretbox_ZEROBYTES = 32; final int crypto_secretbox_BOXZEROBYTES = 16; static public int crypto_secretbox(byte[] c, byte[] m, long mlen, byte[] n, byte[] k) { if (mlen < 32) return -1; xsalsa20.crypto_stream_xor(c, m, mlen, n, k); poly1305.crypto_onetimeauth(c, 16, c, 32, mlen - 32, c); for (int i = 0; i < 16; ++i) c[i] = 0; return 0; } static public int crypto_secretbox_open(byte[] m, byte[] c, long clen, byte[] n, byte[] k) { if (clen < 32) return -1; byte[] subkeyp = new byte[32]; xsalsa20.crypto_stream(subkeyp, 32, n, k); if (poly1305.crypto_onetimeauth_verify(c, 16, c, 32, clen - 32, subkeyp) != 0) return -1; xsalsa20.crypto_stream_xor(m, c, clen, n, k); for (int i = 0; i < 32; ++i) m[i] = 0; return 0; } } jnacl-1.0/src/test/000077500000000000000000000000001325054374600142205ustar00rootroot00000000000000jnacl-1.0/src/test/java/000077500000000000000000000000001325054374600151415ustar00rootroot00000000000000jnacl-1.0/src/test/java/com/000077500000000000000000000000001325054374600157175ustar00rootroot00000000000000jnacl-1.0/src/test/java/com/neilalexander/000077500000000000000000000000001325054374600205325ustar00rootroot00000000000000jnacl-1.0/src/test/java/com/neilalexander/jnacl/000077500000000000000000000000001325054374600216215ustar00rootroot00000000000000jnacl-1.0/src/test/java/com/neilalexander/jnacl/NaClTest.java000066400000000000000000000043151325054374600241440ustar00rootroot00000000000000// // Copyright (c) 2011, Neil Alexander T. // All rights reserved. // // Redistribution and use in source and binary forms, with // or without modification, are permitted provided that the following // conditions are met: // // - Redistributions of source code must retain the above copyright notice, // this list of conditions and the following disclaimer. // - Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. // package com.neilalexander.jnacl; import org.testng.annotations.Test; import static org.fest.assertions.Assertions.assertThat; public class NaClTest { private static String publickey = "0cba66066896ffb51e92bc3c36ffa627c2493770d9b0b4368a2466c801b0184e"; private static String privatekey = "176970653848be5242059e2308dfa30245b93a13befd2ebd09f09b971273b728"; private static byte[] nonce = new byte[24]; @Test public void happy_path() throws Exception { NaCl test = new NaCl(privatekey, publickey); byte[] in = "hi".getBytes(); byte[] foo = test.encrypt(in, nonce); byte[] bar = test.decrypt(foo, nonce); assertThat(NaCl.asHex(in)).isEqualTo("6869"); assertThat(NaCl.asHex(foo)).isEqualTo("00000000000000000000000000000000c0267362f8612dba2bd704aae3f6da44eaed"); assertThat(NaCl.asHex(bar)).isEqualTo("6869"); } } jnacl-1.0/src/test/java/com/neilalexander/jnacl/NaclSecretBoxTest.java000066400000000000000000000057611325054374600260310ustar00rootroot00000000000000package com.neilalexander.jnacl; import com.neilalexander.jnacl.crypto.xsalsa20poly1305; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; import static org.fest.assertions.Assertions.assertThat; public class NaclSecretBoxTest { private byte[] key; private byte[] nonce; private byte[] plaintext; @BeforeMethod public void setUp() throws Exception { key = new byte[]{ (byte) 0x14, (byte) 0x34, (byte) 0xe6, (byte) 0x74, (byte) 0xad, (byte) 0x84, (byte) 0xfd, (byte) 0xfd, (byte) 0xc9, (byte) 0xbc, (byte) 0x1a, (byte) 0xa0, (byte) 0x7, (byte) 0x85, (byte) 0x32, (byte) 0x5c, (byte) 0x8b, (byte) 0x6d, (byte) 0x57, (byte) 0x34, (byte) 0x1f, (byte) 0xc7, (byte) 0xce, (byte) 0x20, (byte) 0xb, (byte) 0xa4, (byte) 0x68, (byte) 0xc, (byte) 0x80, (byte) 0x78, (byte) 0x6d, (byte) 0xda }; nonce = new byte[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; plaintext = new byte[]{ (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x7b, (byte) 0x46, (byte) 0xb7, (byte) 0xae, (byte) 0xc0, (byte) 0xea, (byte) 0x6c, (byte) 0xf4, (byte) 0xea, (byte) 0xf4, (byte) 0xed, (byte) 0xb, (byte) 0x98, (byte) 0x55, (byte) 0xab, (byte) 0x69, (byte) 0x88, (byte) 0x37, (byte) 0xc6, (byte) 0xbe, (byte) 0xb, (byte) 0xa6, (byte) 0x88, (byte) 0x3e, (byte) 0xc5, (byte) 0x26, (byte) 0xf1, (byte) 0xc7, (byte) 0xb9, (byte) 0x97, (byte) 0xaf, (byte) 0xa8 }; } @Test public void test_crypto_secretbox() throws Exception { byte[] ciphertext = new byte[64]; xsalsa20poly1305.crypto_secretbox(ciphertext, plaintext, plaintext.length, nonce, key); byte[] expected_ciphertext = new byte[]{ (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0xd3, (byte) 0x6e, (byte) 0xc5, (byte) 0x2, (byte) 0xe0, (byte) 0x58, (byte) 0x86, (byte) 0xd1, (byte) 0xf0, (byte) 0x27, (byte) 0x9f, (byte) 0x5, (byte) 0x5f, (byte) 0xa5, (byte) 0x25, (byte) 0x54, (byte) 0xd1, (byte) 0x6d, (byte) 0x16, (byte) 0xc1, (byte) 0xb1, (byte) 0x40, (byte) 0x74, (byte) 0xbb, (byte) 0xb8, (byte) 0x3f, (byte) 0xf0, (byte) 0xfd, (byte) 0xd7, (byte) 0x9d, (byte) 0xc2, (byte) 0xfe, (byte) 0x9, (byte) 0x8f, (byte) 0xe, (byte) 0xd4, (byte) 0xa2, (byte) 0xb0, (byte) 0x91, (byte) 0x13, (byte) 0xe, (byte) 0x6b, (byte) 0x5d, (byte) 0xb4, (byte) 0x6a, (byte) 0x20, (byte) 0xa8, (byte) 0x6b }; assertThat(ciphertext).isEqualTo(expected_ciphertext); } }