/**
 * Copyright 2013 Bruno Oliveira, and individual contributors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.abstractj.kalium;

import jnr.ffi.LibraryLoader;
import jnr.ffi.provider.FFIProvider;

public class NaCl {

    public static final Sodium SODIUM_INSTANCE;
    private static final String LIBRARY_NAME = "sodium";

    private NaCl() {
    }

    public interface Sodium {

        public String sodium_version_string();

        public static final int SHA256BYTES = 32;

        public int crypto_hash_sha256_ref(byte[] buffer, String message, long sizeof);

        public static final int SHA512BYTES = 64;

        public int crypto_hash_sha512_ref(byte[] buffer, String message, long sizeof);

        public static final int PUBLICKEY_BYTES = 32;
        public static final int SECRETKEY_BYTES = 32;

        public int crypto_box_curve25519xsalsa20poly1305_ref_keypair(byte[] publicKey, byte[] secretKey);


        public static final int NONCE_BYTES = 24;
        public static final int ZERO_BYTES = 32;
        public static final int BOXZERO_BYTES = 16;

        public void randombytes(byte[] buffer, long size);

        public int crypto_box_curve25519xsalsa20poly1305_ref(byte[] ct, byte[] msg, int length, byte[] nonce, byte[] publicKey, byte[] privateKey);

        public int crypto_box_curve25519xsalsa20poly1305_ref_open(byte[] message, byte[] ct, int length, byte[] nonce, byte[] publicKey, byte[] privateKey);

        public static final int SCALAR_BYTES = 32;

        public int crypto_scalarmult_curve25519_ref(byte[] result, byte[] intValue, byte[] point);

        public static final int XSALSA20_POLY1305_SECRETBOX_KEYBYTES = 32;
        public static final int XSALSA20_POLY1305_SECRETBOX_NONCEBYTES = 24;

        int crypto_secretbox_xsalsa20poly1305_ref(byte[] ct, byte[] msg, int length, byte[] nonce, byte[] key);

        int crypto_secretbox_xsalsa20poly1305_ref_open(byte[] message, byte[] ct, int length, byte[] nonce, byte[] key);

        public static final int SIGNATURE_BYTES = 64;

        int crypto_sign_ed25519_ref_seed_keypair(byte[] publicKey, byte[] secretKey, byte[] seed);

        int crypto_sign_ed25519_ref(byte[] buffer, byte[] bufferLen, byte[] message, int length, byte[] secretKey);

    }

    static {
        LibraryLoader<Sodium> libraryLoader = FFIProvider.getSystemProvider()
                .createLibraryLoader(Sodium.class)
                .library(LIBRARY_NAME);
        SODIUM_INSTANCE = libraryLoader.load();
    }
}
@@ -715,16 +715,111 @@
 rovider;
+%0Aimport jnr.ffi.annotations.In;%0Aimport jnr.ffi.annotations.Out;%0Aimport jnr.ffi.types.u_int64_t;
 %0A%0Apublic
@@ -1135,24 +1135,29 @@
 _sha256_ref(
+@Out 
 byte%5B%5D buffe
@@ -1166,32 +1166,43 @@
  String message,
+ @u_int64_t
  long sizeof);%0A%0A
@@ -1290,24 +1290,29 @@
 _sha512_ref(
+@Out 
 byte%5B%5D buffe
@@ -1329,16 +1329,27 @@
 message,
+ @u_int64_t
  long si
@@ -1757,16 +1757,21 @@
 ombytes(
+@Out 
 byte%5B%5D b
@@ -1776,16 +1776,27 @@
  buffer,
+ @u_int64_t
  long si
@@ -1854,32 +1854,37 @@
 a20poly1305_ref(
+@Out 
 byte%5B%5D ct, byte%5B
@@ -1869,32 +1869,36 @@
 (@Out byte%5B%5D ct,
+ @In
  byte%5B%5D msg, int
@@ -1890,35 +1890,47 @@
 byte%5B%5D msg, 
-int
+@u_int64_t long
  length,
  byte%5B%5D nonc
@@ -1909,32 +1909,36 @@
 4_t long length,
+ @In
  byte%5B%5D nonce, b
@@ -1927,32 +1927,36 @@
 In byte%5B%5D nonce,
+ @In
  byte%5B%5D publicKe
@@ -1949,32 +1949,36 @@
 yte%5B%5D publicKey,
+ @In
  byte%5B%5D privateK
@@ -2041,32 +2041,37 @@
 ly1305_ref_open(
+@Out 
 byte%5B%5D message, 
@@ -2061,32 +2061,36 @@
  byte%5B%5D message,
+ @In
  byte%5B%5D ct, int 
@@ -2081,35 +2081,47 @@
  byte%5B%5D ct, 
-int
+@u_int64_t long
  length,
  byte%5B%5D nonc
@@ -2100,32 +2100,36 @@
 4_t long length,
+ @In
  byte%5B%5D nonce, b
@@ -2118,32 +2118,36 @@
 In byte%5B%5D nonce,
+ @In
  byte%5B%5D publicKe
@@ -2140,32 +2140,36 @@
 yte%5B%5D publicKey,
+ @In
  byte%5B%5D privateK
@@ -2274,24 +2274,29 @@
 ve25519_ref(
+@Out 
 byte%5B%5D resul
@@ -2297,16 +2297,20 @@
  result,
+ @In
  byte%5B%5D 

Add annotations to optimize copying data in to/out of native code, and correct length parameters to be unsigned long long