diff --git a/java/android/OlmLibSdk/olm-sdk/src/androidTest/java/org/matrix/olm/OlmAccountTest.java b/java/android/OlmLibSdk/olm-sdk/src/androidTest/java/org/matrix/olm/OlmAccountTest.java
index 70db63e7069b2b99b777b1e3e37c702bf82d4fd3..45f6e6311d476b06c9d557c7ab980a8f32a51627 100644
--- a/java/android/OlmLibSdk/olm-sdk/src/androidTest/java/org/matrix/olm/OlmAccountTest.java
+++ b/java/android/OlmLibSdk/olm-sdk/src/androidTest/java/org/matrix/olm/OlmAccountTest.java
@@ -173,41 +173,6 @@ public class OlmAccountTest {
         String clearMsg = "String to be signed by olm";
         String signedMsg  = mOlmAccount.signMessage(clearMsg);
         assertNotNull(signedMsg);
-        // TODO add test to unsign the signedMsg and compare it ot clearMsg
+        // additional tests are performed in test01VerifyEd25519Signing()
     }
-
-
-    private void testJni(){
-        OlmManager mgr = new OlmManager();
-        String versionLib = mgr.getOlmLibVersion();
-        Log.d(LOG_TAG, "## testJni(): lib version="+versionLib);
-
-        OlmAccount account = new OlmAccount();
-
-        long accountNativeId = account.getOlmAccountId();
-        Log.d(LOG_TAG, "## testJni(): lib accountNativeId="+accountNativeId);
-
-        JSONObject identityKeys = account.identityKeys();
-        Log.d(LOG_TAG, "## testJni(): identityKeysJson="+identityKeys.toString());
-
-        long maxOneTimeKeys = account.maxOneTimeKeys();
-        Log.d(LOG_TAG, "## testJni(): lib maxOneTimeKeys="+maxOneTimeKeys);
-
-        int generateRetCode = account.generateOneTimeKeys(50);
-        Log.d(LOG_TAG, "## testJni(): generateRetCode="+generateRetCode);
-
-        JSONObject oneTimeKeysKeysJson = account.oneTimeKeys();
-        Log.d(LOG_TAG, "## testJni(): oneTimeKeysKeysJson="+oneTimeKeysKeysJson.toString());
-
-        int asPublishedRetCode = account.markOneTimeKeysAsPublished();
-        Log.d(LOG_TAG, "## testJni(): asPublishedRetCode="+asPublishedRetCode);
-
-        String clearMsg ="My clear message";
-        String signedMsg = account.signMessage(clearMsg);
-        Log.d(LOG_TAG, "## testJni(): signedMsg="+signedMsg);
-
-        account.releaseAccount();
-    }
-
-
 }
diff --git a/java/android/OlmLibSdk/olm-sdk/src/androidTest/java/org/matrix/olm/OlmGroupTest.java b/java/android/OlmLibSdk/olm-sdk/src/androidTest/java/org/matrix/olm/OlmGroupSessionTest.java
similarity index 71%
rename from java/android/OlmLibSdk/olm-sdk/src/androidTest/java/org/matrix/olm/OlmGroupTest.java
rename to java/android/OlmLibSdk/olm-sdk/src/androidTest/java/org/matrix/olm/OlmGroupSessionTest.java
index 5a5ca57fce35ce973a81f545e1668c0de10c94d2..fc3c1f093c584e0cc45068c790b2885a1cce6b1c 100644
--- a/java/android/OlmLibSdk/olm-sdk/src/androidTest/java/org/matrix/olm/OlmGroupTest.java
+++ b/java/android/OlmLibSdk/olm-sdk/src/androidTest/java/org/matrix/olm/OlmGroupSessionTest.java
@@ -17,16 +17,16 @@ import static org.junit.Assert.assertTrue;
 
 @RunWith(AndroidJUnit4.class)
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
-public class OlmGroupTest {
+public class OlmGroupSessionTest {
     private static final String LOG_TAG = "OlmSessionTest";
 
     private static OlmManager mOlmManager;
-    private static OlmOutboundGroupSession mAliceOutboundSession;
+    private static OlmOutboundGroupSession mAliceOutboundGroupSession;
     private static String mAliceSessionIdentifier;
     private static long mAliceMessageIndex;
     public  static final String CLEAR_MESSAGE1 = "Hello!";
     private static String mAliceToBobMessage;
-    private static OlmInboundGroupSession mBobInboundSession;
+    private static OlmInboundGroupSession mBobInboundGroupSession;
     private static String mAliceOutboundSessionKey;
     private static String mBobSessionIdentifier;
     private static String mBobDecryptedMessage;
@@ -53,7 +53,7 @@ public class OlmGroupTest {
     public void test01CreateOutboundSession() {
         // alice creates OUTBOUND GROUP SESSION
         try {
-            mAliceOutboundSession = new OlmOutboundGroupSession();
+            mAliceOutboundGroupSession = new OlmOutboundGroupSession();
         } catch (OlmException e) {
             assertTrue("Exception in OlmOutboundGroupSession, Exception code=" + e.getExceptionCode(), false);
         }
@@ -62,7 +62,7 @@ public class OlmGroupTest {
     @Test
     public void test02GetOutboundGroupSessionIdentifier() {
         // test session ID
-        mAliceSessionIdentifier = mAliceOutboundSession.sessionIdentifier();
+        mAliceSessionIdentifier = mAliceOutboundGroupSession.sessionIdentifier();
         assertNotNull(mAliceSessionIdentifier);
         assertTrue(mAliceSessionIdentifier.length() > 0);
     }
@@ -70,7 +70,7 @@ public class OlmGroupTest {
     @Test
     public void test03GetOutboundGroupSessionKey() {
         // test session Key
-        mAliceOutboundSessionKey = mAliceOutboundSession.sessionKey();
+        mAliceOutboundSessionKey = mAliceOutboundGroupSession.sessionKey();
         assertNotNull(mAliceOutboundSessionKey);
         assertTrue(mAliceOutboundSessionKey.length() > 0);
     }
@@ -78,56 +78,48 @@ public class OlmGroupTest {
     @Test
     public void test04GetOutboundGroupMessageIndex() {
         // test message index before any encryption
-        mAliceMessageIndex = mAliceOutboundSession.messageIndex();
+        mAliceMessageIndex = mAliceOutboundGroupSession.messageIndex();
         assertTrue(0 == mAliceMessageIndex);
     }
 
     @Test
     public void test05OutboundGroupEncryptMessage() {
         // alice encrypts a message to bob
-        mAliceToBobMessage = mAliceOutboundSession.encryptMessage(CLEAR_MESSAGE1);
+        mAliceToBobMessage = mAliceOutboundGroupSession.encryptMessage(CLEAR_MESSAGE1);
         assertFalse(TextUtils.isEmpty(mAliceToBobMessage));
 
         // test message index after encryption is incremented
-        mAliceMessageIndex = mAliceOutboundSession.messageIndex();
-        assertTrue(1== mAliceMessageIndex);
+        mAliceMessageIndex = mAliceOutboundGroupSession.messageIndex();
+        assertTrue(1 == mAliceMessageIndex);
     }
 
     @Test
     public void test06CreateInboundGroupSession() {
         // bob creates INBOUND GROUP SESSION with alice outbound key
         try {
-            mBobInboundSession = new OlmInboundGroupSession(mAliceOutboundSessionKey);
+            mBobInboundGroupSession = new OlmInboundGroupSession(mAliceOutboundSessionKey);
         } catch (OlmException e) {
             assertTrue("Exception in bob OlmInboundGroupSession, Exception code=" + e.getExceptionCode(), false);
         }
     }
 
     @Test
-    public void test07OutboundGroupSessionIdentifiers() {
-        // check session identifiers are equals
-        mAliceSessionIdentifier = mAliceOutboundSession.sessionIdentifier();
-        assertFalse(TextUtils.isEmpty(mAliceSessionIdentifier));
-    }
-
-    @Test
-    public void test08InboundGroupSessionIdentifiers() {
-        // check session identifiers are equals
-        mBobSessionIdentifier = mBobInboundSession.sessionIdentifier();
+    public void test08GetInboundGroupSessionIdentifier() {
+        // check both session identifiers are equals
+        mBobSessionIdentifier = mBobInboundGroupSession.sessionIdentifier();
         assertFalse(TextUtils.isEmpty(mBobSessionIdentifier));
-        assertTrue(mAliceSessionIdentifier.equals(mBobSessionIdentifier));
     }
 
     @Test
-    public void test09SessionIdentifiersIdentical() {
-        // check session identifiers are equals
+    public void test09SessionIdentifiersAreIdentical() {
+        // check both session identifiers are equals: alice vs bob
         assertTrue(mAliceSessionIdentifier.equals(mBobSessionIdentifier));
     }
 
     @Test
     public void test10InboundDecryptMessage() {
         // test decrypted message
-        mBobDecryptedMessage = mBobInboundSession.decryptMessage(mAliceToBobMessage);
+        mBobDecryptedMessage = mBobInboundGroupSession.decryptMessage(mAliceToBobMessage);
         assertFalse(TextUtils.isEmpty(mBobDecryptedMessage));
         assertTrue(mBobDecryptedMessage.equals(CLEAR_MESSAGE1));
     }
@@ -141,12 +133,12 @@ public class OlmGroupTest {
     @Test
     public void test12ReleaseOutboundSession() {
         // release group sessions
-        mAliceOutboundSession.releaseSession();
+        mAliceOutboundGroupSession.releaseSession();
     }
 
     @Test
     public void test13ReleaseInboundSession() {
         // release group sessions
-        mBobInboundSession.releaseSession();
+        mBobInboundGroupSession.releaseSession();
     }
 }
diff --git a/java/android/OlmLibSdk/olm-sdk/src/androidTest/java/org/matrix/olm/OlmSessionTest.java b/java/android/OlmLibSdk/olm-sdk/src/androidTest/java/org/matrix/olm/OlmSessionTest.java
index 6056466f16005676656bff40c9e25f96ba1d2870..311d6a86092f53348758cb9ae7c9c76cac374647 100644
--- a/java/android/OlmLibSdk/olm-sdk/src/androidTest/java/org/matrix/olm/OlmSessionTest.java
+++ b/java/android/OlmLibSdk/olm-sdk/src/androidTest/java/org/matrix/olm/OlmSessionTest.java
@@ -250,5 +250,4 @@ public class OlmSessionTest {
         // must be the same for both ends of the conversation
         assertTrue(aliceSessionId.equals(bobSessionId));
     }
-
 }
diff --git a/java/android/OlmLibSdk/olm-sdk/src/androidTest/java/org/matrix/olm/OlmUtilityTest.java b/java/android/OlmLibSdk/olm-sdk/src/androidTest/java/org/matrix/olm/OlmUtilityTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..5175424b94e3a5cd399c1e005d73ff1ab4cb00fd
--- /dev/null
+++ b/java/android/OlmLibSdk/olm-sdk/src/androidTest/java/org/matrix/olm/OlmUtilityTest.java
@@ -0,0 +1,89 @@
+package org.matrix.olm;
+
+import android.support.test.runner.AndroidJUnit4;
+import android.text.TextUtils;
+import android.util.Log;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.MethodSorters;
+
+import java.util.Iterator;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+@RunWith(AndroidJUnit4.class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+public class OlmUtilityTest {
+    private static final String LOG_TAG = "OlmAccountTest";
+    private static final int GENERATION_ONE_TIME_KEYS_NUMBER = 50;
+
+    private static OlmManager mOlmManager;
+
+    @BeforeClass
+    public static void setUpClass(){
+        // load native lib
+        mOlmManager = new OlmManager();
+
+        String version = mOlmManager.getOlmLibVersion();
+        assertNotNull(version);
+        Log.d(LOG_TAG, "## setUpClass(): lib version="+version);
+    }
+
+    /**
+     * Test the signing API
+     */
+    @Test
+    public void test01VerifyEd25519Signing() {
+        String fingerPrintKey = null;
+        String errorMsg = new String();
+        String message = "{\"key1\":\"value1\",\"key2\":\"value2\"};";
+
+        // create account
+        OlmAccount account = new OlmAccount();
+        assertNotNull(account);
+
+        // sign message
+        String messageSignature = account.signMessage(message);
+        assertNotNull(messageSignature);
+
+        // get identity key
+        JSONObject identityKeysJson = account.identityKeys();
+        assertNotNull(identityKeysJson);
+        try {
+            fingerPrintKey = identityKeysJson.getString(OlmAccount.JSON_KEY_FINGER_PRINT_KEY);
+            assertTrue("fingerprint key missing",!TextUtils.isEmpty(fingerPrintKey));
+        } catch (JSONException e) {
+            e.printStackTrace();
+            assertTrue("Exception MSg="+e.getMessage(), false);
+        }
+
+        // instance utility
+        OlmUtility utility = new OlmUtility();
+        boolean isVerified = utility.verifyEd25519Signature(messageSignature, fingerPrintKey, message, errorMsg);
+        assertTrue(isVerified);
+
+        utility.releaseUtility();
+    }
+
+
+    @Test
+    public void test02sha256() {
+        OlmUtility utility = new OlmUtility();
+        String msgToHash = "The quick brown fox jumps over the lazy dog";
+
+        String hashResult = utility.sha256(msgToHash);
+        assertFalse(TextUtils.isEmpty(hashResult));
+
+        utility.releaseUtility();
+    }
+}
diff --git a/java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmAccount.java b/java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmAccount.java
index bc9c936da29bf7fab04802da159543c17cbc4ddd..ea8d6183e39f1897d420fec33f2dff5269f74db6 100644
--- a/java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmAccount.java
+++ b/java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmAccount.java
@@ -71,7 +71,6 @@ public class OlmAccount implements Serializable {
     /**
      * Release native account and invalid its JAVA reference counter part.<br>
      * Public API for {@link #releaseAccountJni()}.
-     * To be called before any other API call.
      */
     public void releaseAccount(){
         releaseAccountJni();
diff --git a/java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmException.java b/java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmException.java
index d4c642fd54ff232060562b35c258562641fb60f6..68e02fda0b140b0bb88c249becb25e001c411a19 100644
--- a/java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmException.java
+++ b/java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmException.java
@@ -16,17 +16,33 @@
 
 package org.matrix.olm;
 
+/**
+ * Exception class to identify specific Olm SDk exceptions.
+ */
 public class OlmException extends Exception {
     // exception codes
-    public static final int EXCEPTION_CODE_INIT_NEW_SESSION_FAILURE = 0;
-    public static final int EXCEPTION_CODE_INIT_OUTBOUND_GROUP_SESSION = 1;
-    public static final int EXCEPTION_CODE_INIT_INBOUND_GROUP_SESSION = 2;
+    public static final int EXCEPTION_CODE_CREATE_OUTBOUND_GROUP_SESSION = 0;
+    public static final int EXCEPTION_CODE_CREATE_INBOUND_GROUP_SESSION = 1;
+    public static final int EXCEPTION_CODE_INIT_OUTBOUND_GROUP_SESSION = 2;
+    public static final int EXCEPTION_CODE_INIT_INBOUND_GROUP_SESSION = 3;
+
+    // exception human readable messages
+    public static final String EXCEPTION_MSG_NEW_OUTBOUND_GROUP_SESSION = "failed to create a new outbound group Session";
+    public static final String EXCEPTION_MSG_NEW_INBOUND_GROUP_SESSION = "failed to create a new inbound group Session";
+    public static final String EXCEPTION_MSG_INIT_OUTBOUND_GROUP_SESSION = "failed to initialize a new outbound group Session";
+    public static final String EXCEPTION_MSG_INIT_INBOUND_GROUP_SESSION = "failed to initialize a new inbound group Session";
 
+    /** exception code to be taken from: {@link #EXCEPTION_CODE_CREATE_OUTBOUND_GROUP_SESSION} {@link #EXCEPTION_CODE_CREATE_INBOUND_GROUP_SESSION}
+     * {@link #EXCEPTION_CODE_INIT_OUTBOUND_GROUP_SESSION} {@link #EXCEPTION_CODE_INIT_INBOUND_GROUP_SESSION}**/
     private final int mCode;
 
-    public OlmException(int aExceptionCode) {
+    /** Human readable message description **/
+    private final String mMessage;
+
+    public OlmException(int aExceptionCode, String aExceptionMessage) {
         super();
         mCode = aExceptionCode;
+        mMessage = aExceptionMessage;
     }
 
     public int getExceptionCode() {
diff --git a/java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmInboundGroupSession.java b/java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmInboundGroupSession.java
index 86f86c45d9555f05fe273d14a9d68bcb1818697d..d7d9a1c2cd45989ff1bb2ce040ca8ec38e644a7d 100644
--- a/java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmInboundGroupSession.java
+++ b/java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmInboundGroupSession.java
@@ -45,26 +45,25 @@ public class OlmInboundGroupSession implements Serializable {
     /**
      * Constructor.<br>
      * Create and save a new native session instance ID and start a new inbound group session.
-     * The session key parameter is retrieved from a outbound group session
+     * The session key parameter is retrieved from an outbound group session
      * See {@link #initNewSession()} and {@link #initInboundGroupSessionWithSessionKey(String)}
      * @param aSessionKey session key
-     * @throws OlmException
+     * @throws OlmException constructor failure
      */
     public OlmInboundGroupSession(String aSessionKey) throws OlmException {
         if(initNewSession()) {
             if( 0 != initInboundGroupSessionWithSessionKey(aSessionKey)) {
                 releaseSession();// prevent memory leak before throwing
-                throw new OlmException(OlmException.EXCEPTION_CODE_INIT_INBOUND_GROUP_SESSION);
+                throw new OlmException(OlmException.EXCEPTION_CODE_INIT_INBOUND_GROUP_SESSION,OlmException.EXCEPTION_MSG_INIT_INBOUND_GROUP_SESSION);
             }
         } else {
-            throw new OlmException(OlmException.EXCEPTION_CODE_INIT_NEW_SESSION_FAILURE);
+            throw new OlmException(OlmException.EXCEPTION_CODE_CREATE_INBOUND_GROUP_SESSION, OlmException.EXCEPTION_MSG_NEW_INBOUND_GROUP_SESSION);
         }
     }
 
     /**
      * Release native session and invalid its JAVA reference counter part.<br>
      * Public API for {@link #releaseSessionJni()}.
-     * To be called before any other API call.
      */
     public void releaseSession(){
         releaseSessionJni();
@@ -81,8 +80,7 @@ public class OlmInboundGroupSession implements Serializable {
     private native void releaseSessionJni();
 
     /**
-     * Create and save the session native instance ID.
-     * Wrapper for {@link #initNewSessionJni()}.<br>
+     * Create and save the session native instance ID.<br>
      * To be called before any other API call.
      * @return true if init succeed, false otherwise.
      */
diff --git a/java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmOutboundGroupSession.java b/java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmOutboundGroupSession.java
index bca7ab3c73551f5a18f01841f49562ec48b044b1..7c2c42b58f48e13f61e2f61164db9cc92cde6ed2 100644
--- a/java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmOutboundGroupSession.java
+++ b/java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmOutboundGroupSession.java
@@ -40,23 +40,22 @@ public class OlmOutboundGroupSession {
      * Create and save a new session native instance ID and
      * initialise a new outbound group session.<br>
      * See {@link #initNewSession()} and {@link #initOutboundGroupSession()}
-     * @throws OlmException
+     * @throws OlmException constructor failure
      */
     public OlmOutboundGroupSession() throws OlmException {
         if(initNewSession()) {
             if( 0 != initOutboundGroupSession()) {
                 releaseSession();// prevent memory leak before throwing
-                throw new OlmException(OlmException.EXCEPTION_CODE_INIT_OUTBOUND_GROUP_SESSION);
+                throw new OlmException(OlmException.EXCEPTION_CODE_INIT_OUTBOUND_GROUP_SESSION, OlmException.EXCEPTION_MSG_INIT_OUTBOUND_GROUP_SESSION);
             }
         } else {
-            throw new OlmException(OlmException.EXCEPTION_CODE_INIT_NEW_SESSION_FAILURE);
+            throw new OlmException(OlmException.EXCEPTION_CODE_CREATE_OUTBOUND_GROUP_SESSION, OlmException.EXCEPTION_MSG_NEW_OUTBOUND_GROUP_SESSION);
         }
     }
 
     /**
      * Release native session and invalid its JAVA reference counter part.<br>
      * Public API for {@link #releaseSessionJni()}.
-     * To be called before any other API call.
      */
     public void releaseSession() {
         releaseSessionJni();        
diff --git a/java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmSession.java b/java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmSession.java
index b356cbb61d5fe9a92b08717fb663503268dc9563..8574f959709bab83ad1f1d282d4a072e39f0c409 100644
--- a/java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmSession.java
+++ b/java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmSession.java
@@ -63,7 +63,6 @@ public class OlmSession implements Serializable {
     /**
      * Release native session and invalid its JAVA reference counter part.<br>
      * Public API for {@link #releaseSessionJni()}.
-     * To be called before any other API call.
      */
     public void releaseSession(){
         releaseSessionJni();
@@ -128,19 +127,19 @@ public class OlmSession implements Serializable {
      * Public API for {@link #initInboundSessionJni(long, String)}.
      * This API may be used to process a "m.room.encrypted" event when type = 1 (PRE_KEY).
      * @param aAccount the account to associate with this session
-     * @param aOneTimeKeyMsg PRE KEY message
+     * @param aPreKeyMsg PRE KEY message
      * @return this if operation succeed, null otherwise
      */
-    public OlmSession initInboundSessionWithAccount(OlmAccount aAccount, String aOneTimeKeyMsg) {
+    public OlmSession initInboundSessionWithAccount(OlmAccount aAccount, String aPreKeyMsg) {
         OlmSession retObj=null;
 
-        if((null==aAccount) || TextUtils.isEmpty(aOneTimeKeyMsg)){
+        if((null==aAccount) || TextUtils.isEmpty(aPreKeyMsg)){
             Log.e(LOG_TAG, "## initInboundSessionWithAccount(): invalid input parameters");
         } else {
             // set the account of this session
             mOlmAccount = aAccount;
 
-            if( 0 == initInboundSessionJni(mOlmAccount.getOlmAccountId(), aOneTimeKeyMsg)) {
+            if( 0 == initInboundSessionJni(mOlmAccount.getOlmAccountId(), aPreKeyMsg)) {
                 retObj = this;
             }
         }
@@ -156,22 +155,23 @@ public class OlmSession implements Serializable {
      * incoming PRE_KEY({@link OlmMessage#MESSAGE_TYPE_PRE_KEY}) message based on the sender identity key.<br>
      * Public API for {@link #initInboundSessionFromIdKeyJni(long, String, String)}.
      * This API may be used to process a "m.room.encrypted" event when type = 1 (PRE_KEY).
+     * This method must only be called the first time a pre-key message is received from an inbound session.
      * @param aAccount the account to associate with this session
      * @param aTheirIdentityKey the sender identity key
-     * @param aOneTimeKeyMsg PRE KEY message
+     * @param aPreKeyMsg PRE KEY message
      * @return this if operation succeed, null otherwise
      * TODO unit test missing: initInboundSessionWithAccountFrom
      */
-    public OlmSession initInboundSessionWithAccountFrom(OlmAccount aAccount, String aTheirIdentityKey, String aOneTimeKeyMsg) {
+    public OlmSession initInboundSessionWithAccountFrom(OlmAccount aAccount, String aTheirIdentityKey, String aPreKeyMsg) {
         OlmSession retObj=null;
 
-        if((null==aAccount) || TextUtils.isEmpty(aOneTimeKeyMsg)){
+        if((null==aAccount) || TextUtils.isEmpty(aPreKeyMsg)){
             Log.e(LOG_TAG, "## initInboundSessionWithAccount(): invalid input parameters");
         } else {
             // set the account of this session
             mOlmAccount = aAccount;
 
-            if(0 == initInboundSessionFromIdKeyJni(mOlmAccount.getOlmAccountId(), aTheirIdentityKey, aOneTimeKeyMsg)){
+            if(0 == initInboundSessionFromIdKeyJni(mOlmAccount.getOlmAccountId(), aTheirIdentityKey, aPreKeyMsg)){
                 retObj = this;
             }
         }
diff --git a/java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmUtility.java b/java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmUtility.java
new file mode 100644
index 0000000000000000000000000000000000000000..e2a085d32befa7413305cb4c5c1f99db9a02a7c8
--- /dev/null
+++ b/java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmUtility.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright 2016 OpenMarket Ltd
+ *
+ * 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.matrix.olm;
+
+import android.text.TextUtils;
+import android.util.Log;
+
+import java.io.Serializable;
+
+public class OlmUtility implements Serializable {
+    private static final String LOG_TAG = "OlmUtility";
+
+    /** raw pointer value returned by JNI.
+     * this value uniquely identifies this utility instance.
+     **/
+    private long mNativeOlmUtilityId;
+
+    public OlmUtility() {
+        initUtility();
+    }
+
+    /**
+     * Getter on the session ID.
+     * @return native session ID
+     */
+    public long getOlmUtilityId(){
+        return mNativeOlmUtilityId;
+    }
+
+    /**
+     * Create a native utility instance.
+     * To be called before any other API call.
+     * @return true if init succeed, false otherwise.
+     */
+    private boolean initUtility() {
+        boolean retCode = false;
+        if(0 != (mNativeOlmUtilityId = initUtilityJni())){
+            retCode = true;
+        }
+        return retCode;
+    }
+    private native long initUtilityJni();
+
+    /**
+     * Release native instance.<br>
+     * Public API for {@link #releaseUtilityJni()}.
+     */
+    public void releaseUtility(){
+        releaseUtilityJni();
+        mNativeOlmUtilityId = 0;
+    }
+    private native void releaseUtilityJni();
+
+    /**
+     * Verify an ed25519 signature.<br>
+     * If the signature is verified, the method returns true. If false is returned, an error description is provided in aError.
+     * If the key was too small, aError is set to "OLM.INVALID_BASE64".
+     * If the signature was invalid, aError is set to "OLM.BAD_MESSAGE_MAC".<br>
+     * @param aSignature the base64-encoded message signature to be checked.
+     * @param aFingerprintKey the ed25519 key
+     * @param aMessage the message which was signed
+     * @param aError error message description
+     * @return true if the signature is verified, false otherwise
+     */
+    public boolean verifyEd25519Signature(String aSignature, String aFingerprintKey, String aMessage, String aError) {
+        boolean retCode = false;
+        OlmUtility retObj=null;
+
+        if(null == aError) {
+            Log.e(LOG_TAG, "## verifyEd25519Signature(): invalid input error parameter");
+        }
+        else if(TextUtils.isEmpty(aSignature) || TextUtils.isEmpty(aFingerprintKey) || TextUtils.isEmpty(aMessage)){
+            Log.e(LOG_TAG, "## verifyEd25519Signature(): invalid input parameters");
+        } else {
+            String errorRetValue = verifyEd25519SignatureJni(aSignature,aFingerprintKey, aMessage);
+            if(null == errorRetValue) {
+                aError="";
+                retCode = true;
+            } else {
+                aError = errorRetValue;
+            }
+        }
+
+        return retCode;
+    }
+    private native String verifyEd25519SignatureJni(String aSignature, String aFingerprintKey, String aMessage);
+
+
+    /**
+     * Compute the hash(SHA-256) value of the string given in parameter(aMessageToHash).<br>
+     * The hash value is the returned by the method.
+     * @param aMessageToHash message to be hashed
+     * @return hash value if operation succeed, null otherwise
+     */
+     public String sha256(String aMessageToHash) {
+        String hashRetValue = null;
+
+         if(null != aMessageToHash){
+            hashRetValue = sha256Jni(aMessageToHash);
+         }
+
+        return hashRetValue;
+
+    }
+    private native String sha256Jni(String aMessage);
+
+
+    // TODO missing API: initWithSerializedData
+    // TODO missing API: serializeDataWithKey
+    // TODO missing API: initWithCoder
+    // TODO missing API: encodeWithCoder
+}
+