androidabe

git clone git://git.codymlewis.com/androidabe.git
Log | Files | Refs | Submodules | README

commit 7e85edd8a891d06023e526e67974805436060a02
parent c174ad14a2870b49248bfb44f50a07d6e8acec21
Author: Cody Lewis <cody@codymlewis.com>
Date:   Thu, 28 May 2020 15:08:12 +1000

Added consts and removed memory leaks

Diffstat:
Mabe/src/main/cpp/native-lib.c | 152++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------
Mabe/src/main/cpp/native-lib.h | 48+++++++++++++++++++++++++++++++++++++++++-------
Mabe/src/main/java/com/codymlewis/abe/Functions.java | 5+++++
Mabe/src/main/java/com/codymlewis/abe/Keychain.java | 10++++++++++
Mabe/src/main/java/com/codymlewis/abe/Token.java | 23+++++++++++++++++++----
Mapp/build.gradle | 3++-
Mapp/src/main/java/com/codymlewis/androidabe/MainActivity.java | 18++++++++++++++++--
Mwearapp/build.gradle | 2+-
8 files changed, 221 insertions(+), 40 deletions(-)

diff --git a/abe/src/main/cpp/native-lib.c b/abe/src/main/cpp/native-lib.c @@ -5,6 +5,7 @@ #include <pbc.h> #include <pbc_test.h> #include <string.h> +#include <stdlib.h> #include <sys/types.h> #include <malloc.h> @@ -15,7 +16,7 @@ #include "native-lib.h" -jbyteArray buffer_to_jbyteArray(JNIEnv* env, unsigned char* buf, size_t buf_len) +jbyteArray buffer_to_jbyteArray(JNIEnv* env, const unsigned char* buf, const int buf_len) { jbyteArray jba = (*env)->NewByteArray(env, buf_len); jbyte* jbuf = (*env)->GetByteArrayElements(env, jba, NULL); @@ -28,20 +29,20 @@ jbyteArray buffer_to_jbyteArray(JNIEnv* env, unsigned char* buf, size_t buf_len) } -unsigned char* jbyteArray_to_buffer(JNIEnv* env, jbyteArray jba) +unsigned char* jbyteArray_to_buffer(JNIEnv* env, const jbyteArray jba) { jsize buf_len = (*env)->GetArrayLength(env, jba); jbyte* jbuf = (*env)->GetByteArrayElements(env, jba, NULL); unsigned char* buf = malloc(sizeof(unsigned char) * buf_len); for (size_t i = 0; i < buf_len; ++i) { - buf[i] = jbuf[i]; + buf[i] = (unsigned char) jbuf[i]; } (*env)->ReleaseByteArrayElements(env, jba, jbuf, JNI_ABORT); return buf; } -void init_pairing(JNIEnv* env, pairing_t* pairing, jstring params) +void init_pairing(JNIEnv* env, pairing_t* pairing, const jstring params) { const char *s = (*env)->GetStringUTFChars(env, params, NULL); size_t count = strlen(s) + 1; @@ -49,7 +50,7 @@ void init_pairing(JNIEnv* env, pairing_t* pairing, jstring params) (*env)->ReleaseStringUTFChars(env, params, s); } -jbyteArray element_to_jbyteArray(JNIEnv* env, pairing_t pairing, element_t element, char* group) +int pairing_length_bytes(pairing_t pairing, const char* group) { int n; if (strcmp(group, "G1")) { @@ -61,8 +62,15 @@ jbyteArray element_to_jbyteArray(JNIEnv* env, pairing_t pairing, element_t eleme } else { n = pairing_length_in_bytes_Zr(pairing); } - unsigned char* buf = pbc_malloc(n); - element_to_bytes(buf, element); + return n; +} + +jbyteArray element_to_jbyteArray(JNIEnv* env, pairing_t pairing, element_t e, const char* group) +{ + unsigned char* buf; + size_t n = (size_t) pairing_length_bytes(pairing, group); + buf = pbc_malloc(n); + element_to_bytes(buf, e); jbyteArray result = buffer_to_jbyteArray(env, buf, n); pbc_free(buf); return result; @@ -74,15 +82,16 @@ int element_from_jbyteArray(JNIEnv* env, element_t element, jbyteArray jba) return 1; } -int clear_elements(element_t* els, int n) +int clear_elements(element_t* els, const size_t n) { - for (int i = 0; i < n; ++i) { + for (size_t i = 0; i < n; ++i) { element_clear(els[i]); } return 1; } -int hash_1(unsigned char* buf, int len, element_t e) // Remember to init e! +// The following function fills e with md correctly, but gets padded with 0s at the end +int hash_1(unsigned char* buf, const size_t len, element_t e) // Remember to init e! { SHA256_CTX c; SHA256_Init(&c); @@ -93,12 +102,22 @@ int hash_1(unsigned char* buf, int len, element_t e) // Remember to init e! return 1; } -int hash_2(unsigned char* buf, int len, element_t e) +int hash_2(unsigned char* buf, const size_t len, element_t e) { element_from_bytes(e, buf); return 1; } +JNIEXPORT jbyteArray JNICALL +Java_com_codymlewis_abe_Functions_test( + JNIEnv* env, + jobject thiz, + jbyteArray jba) +{ + unsigned char* ba = jbyteArray_to_buffer(env, jba); + return buffer_to_jbyteArray(env, ba, strlen((char*) ba)); +} + JNIEXPORT jint JNICALL Java_com_codymlewis_abe_Functions_setup( JNIEnv* env, @@ -112,15 +131,17 @@ Java_com_codymlewis_abe_Functions_setup( init_pairing(env, &pairing, Keychain_getGroupData(env, Keychain, keychain)); element_init_G2(g, pairing); - element_random(g); + element_random(g); // Is g chosen correctly? element_pp_t g_pp; element_pp_init(g_pp, g); + jbyteArray g_jba = element_to_jbyteArray(env, pairing, g, "G2"); + Keychain_setG(env, Keychain, keychain, g_jba); element_t y[k + 3]; element_t Y[k + 3]; jmethodID addSecret = (*env)->GetMethodID(env, Keychain, "addSecret", "([B)V"); jmethodID addPublic = (*env)->GetMethodID(env, Keychain, "addPublic", "([B)V"); - for (int i = 0; i < k + 3; ++i) { + for (size_t i = 0; i < k + 3; ++i) { element_init_Zr(y[i], pairing); element_random(y[i]); jbyteArray s = element_to_jbyteArray(env, pairing, y[i], "Zr"); @@ -131,8 +152,8 @@ Java_com_codymlewis_abe_Functions_setup( (*env)->CallVoidMethod(env, keychain, addPublic, p); } - clear_elements(y, k + 3); - clear_elements(Y, k + 3); + clear_elements(y, (size_t) k + 3); + clear_elements(Y, (size_t) k + 3); pairing_clear(pairing); element_pp_clear(g_pp); element_clear(g); @@ -150,7 +171,6 @@ Java_com_codymlewis_abe_Functions_issueToken( jclass Keychain = get_Keychain(env); jclass Token = get_Token(env); - // Add attributes and ID to keychain pairing_t pairing; init_pairing(env, &pairing, Keychain_getGroupData(env, Keychain, keychain)); element_t h, hbar; @@ -181,27 +201,109 @@ Java_com_codymlewis_abe_Functions_proveKnowledge( pairing_t pairing; init_pairing(env, &pairing, Keychain_getGroupData(env, Keychain, keychain)); - // Check h is in G_2 + // TODO: Check h is in G_2 + element_t h; + element_init_G1(h, pairing); + element_from_jbyteArray(env, h, Token_getSigma(env, Token, token, "getSigma1")); + int k = Keychain_getK(env, Keychain, keychain); element_t Adash[k + 1]; - for (int i = 0; i < k + 1; ++i) { + for (size_t i = 0; i < k + 1; ++i) { element_init_Zr(Adash[i], pairing); element_random(Adash[i]); Token_addAdash(env, token, addAdash, element_to_jbyteArray(env, pairing, Adash[i], "Zr")); } - element_t Tbar; - element_init_G1(Tbar, pairing); element_t hbar; element_init_G1(hbar, pairing); element_from_jbyteArray(env, hbar, Token_getSigma(env, Token, token, "getSigmabar1")); - element_t H_2; - element_init_G1(H_2, pairing); + + element_t H_content; + element_init_G1(H_content, pairing); + unsigned char* g_buf = jbyteArray_to_buffer(env, Keychain_getG(env, Keychain, keychain)); + char n_buf[strlen((char*) g_buf) + 1]; + sprintf(n_buf, "%s%x", g_buf, Token_getN(env, Token, token) + 1); + hash_2((unsigned char*) n_buf, strlen(n_buf), H_content); + element_pow_zn(H_content, H_content, Adash[0]); + size_t n = (size_t) pairing_length_bytes(pairing, "G1"); + unsigned char* H_buffer = pbc_malloc(n); + element_to_bytes(H_buffer, H_content); + hash_1(H_buffer, n, H_content); + element_pow_zn(H_content, hbar, H_content); + Token_setTbar(env, Token, token, element_to_jbyteArray(env, pairing, H_content, "G1")); + pbc_free(g_buf); + + unsigned char* pok; + n = (size_t) pairing_length_bytes(pairing, "G1"); + pok = pbc_malloc(n); + element_t temp; + element_init_G1(temp, pairing); + jmethodID getAttribute = get_Token_getAttribute_ID(env, Token); + element_t H_1_a_i; + element_init_Zr(H_1_a_i, pairing); + element_t m_i; + element_init_Zr(m_i, pairing); + unsigned char* m_i_buf; + for (int i = 0; i < k; ++i) { + if (i == 0) { + element_pow_zn(temp, h, Adash[0]); + element_to_bytes(pok, temp); + } else { + // calculate m_i = H_1(a_i) + a'_i + unsigned char* a_i = jbyteArray_to_buffer(env, Token_getAttribute(env, token, getAttribute, i)); + hash_1(a_i, strlen((char*) a_i), H_1_a_i); + element_add(m_i, H_1_a_i, Adash[i]); + // set pok = pok & h^(m_i) + element_pow_zn(m_i, h, m_i); + m_i_buf = pbc_malloc(n); + element_to_bytes(m_i_buf, m_i); + for (int i = 0; i < n; ++i) { + pok[i] = pok[i] & m_i_buf[i]; + } + pbc_free(m_i_buf); + } + } + Token_setPok(env, Token, token, buffer_to_jbyteArray(env, pok, n)); + pbc_free(pok); + element_clear(H_1_a_i); + element_clear(m_i); + element_clear(temp); pairing_clear(pairing); element_clear(hbar); - element_clear(Tbar); - element_clear(H_2); - clear_elements(Adash, k + 1); + element_clear(H_content); + clear_elements(Adash, (size_t) k + 1); + return 1; +} + +JNIEXPORT jint JNICALL +Java_com_codymlewis_abe_Functions_completeTokenIssue( + JNIEnv* env, + jobject thiz, + jobject keychain, + jobject token) +{ + jclass Keychain = get_Keychain(env); + jclass Token = get_Token(env); + pairing_t pairing; + init_pairing(env, &pairing, Keychain_getGroupData(env, Keychain, keychain)); + + // TODO check attributes and pok + + char I[64]; + sprintf(I, "%lf%d", pbc_get_time(), Token_getN(env, Token, token)); + + pairing_clear(pairing); + return 1; +} + +JNIEXPORT jboolean JNICALL +Java_com_codymlewis_abe_Functions_checkSigmas( + JNIEnv* env, + jobject thiz, + jobject keychain, + jobject token) +{ + // TODO check that the sigmas calculate correctly, particularly the 2 ones return 1; } \ No newline at end of file diff --git a/abe/src/main/cpp/native-lib.h b/abe/src/main/cpp/native-lib.h @@ -15,7 +15,7 @@ * @param buf_len number of bytes in the byte array * @return Java byte array containing a copy of the C byte array data */ -jbyteArray buffer_to_jbyteArray(JNIEnv* env, unsigned char* buf, size_t buf_len); +jbyteArray buffer_to_jbyteArray(JNIEnv* env, const unsigned char* buf, const int buf_len); /** @@ -24,7 +24,7 @@ jbyteArray buffer_to_jbyteArray(JNIEnv* env, unsigned char* buf, size_t buf_len) * @param jba Java byte array * @return C byte array containing a copy of the java byte array data */ -unsigned char* jbyteArray_to_buffer(JNIEnv* env, jbyteArray jba); +unsigned char* jbyteArray_to_buffer(JNIEnv* env, const jbyteArray jba); /** * Read a file asset and generate the pairing @@ -33,7 +33,9 @@ unsigned char* jbyteArray_to_buffer(JNIEnv* env, jbyteArray jba); * @param assetManager AssetManager java object * @param assetName Name of file to use */ -void init_pairing(JNIEnv* env, pairing_t* pairing, jstring params); +void init_pairing(JNIEnv* env, pairing_t* pairing, const jstring params); + +int pairing_length_bytes(pairing_t pairing, const char* group); /** * Convert an element to a Java byte array @@ -43,7 +45,7 @@ void init_pairing(JNIEnv* env, pairing_t* pairing, jstring params); * @param group Name of the group that the element is from * @return Java byte array of the elements data */ -jbyteArray element_to_jbyteArray(JNIEnv* env, pairing_t pairing, element_t element, char* group); +jbyteArray element_to_jbyteArray(JNIEnv* env, pairing_t pairing, element_t element, const char* group); /** * Convert a Java byte array to an element @@ -60,7 +62,7 @@ int element_from_jbyteArray(JNIEnv* env, element_t element, jbyteArray jba); * @param n Number of elements * @return 1 on completion */ -int clear_elements(element_t* els, int n); +int clear_elements(element_t* els, const size_t n); /** * A normal hash function @@ -69,7 +71,7 @@ int clear_elements(element_t* els, int n); * @param e Element to put the resulting hash into * @return 1 on completion */ -int hash_1(unsigned char* buf, int len, element_t e); +int hash_1(unsigned char* buf, const size_t len, element_t e); /** * Group based hash function, in this case the group is not used so it is simply the identity @@ -79,7 +81,7 @@ int hash_1(unsigned char* buf, int len, element_t e); * @param e Element to put the resulting hash into * @return 1 on completion */ -int hash_2(unsigned char* buf, int len, element_t e); +int hash_2(unsigned char* buf, const size_t len, element_t e); // Keychain Java related functions jclass get_Keychain(JNIEnv* env) { @@ -96,6 +98,16 @@ jstring Keychain_getGroupData(JNIEnv* env, jclass Keychain, jobject keychain) { return (jstring) (*env)->CallObjectMethod(env, keychain, getGroupData); } +void Keychain_setG(JNIEnv* env, jclass Keychain, jobject keychain, jbyteArray g) { + jmethodID setG = (*env)->GetMethodID(env, Keychain, "setG", "([B)V"); + (*env)->CallVoidMethod(env, keychain, setG, g); +} + +jbyteArray Keychain_getG(JNIEnv* env, jclass Keychain, jobject keychain) { + jmethodID getG = (*env)->GetMethodID(env, Keychain, "getG", "()[B"); + return (jbyteArray) (*env)->CallObjectMethod(env, keychain, getG); +} + // Token Java related functions jclass get_Token(JNIEnv* env) { return (*env)->FindClass(env, "com/codymlewis/abe/Token"); @@ -116,6 +128,11 @@ void Token_setN(JNIEnv* env, jclass Token, jobject token, int n) { (*env)->CallVoidMethod(env, token, setN, n); } +jint Token_getN(JNIEnv* env, jclass Token, jobject token) { + jmethodID getN = (*env)->GetMethodID(env, Token, "getN", "()I"); + return (*env)->CallIntMethod(env, token, getN); +} + jmethodID get_Token_addAdash_ID(JNIEnv* env, jclass Token) { return (*env)->GetMethodID(env, Token, "addAdash", "([B)V"); } @@ -124,5 +141,22 @@ void Token_addAdash(JNIEnv* env, jobject token, jmethodID addAdash, jbyteArray j (*env)->CallVoidMethod(env, token, addAdash, jba); } +void Token_setTbar(JNIEnv* env, jclass Token, jobject token, jbyteArray jba) { + jmethodID setTbar = (*env)->GetMethodID(env, Token, "setTbar", "([B)V"); + (*env)->CallVoidMethod(env, token, setTbar, jba); +} + +jmethodID get_Token_getAttribute_ID(JNIEnv* env, jclass Token) { + return (*env)->GetMethodID(env, Token, "getAttribute", "(I)[B"); +} + +jbyteArray Token_getAttribute(JNIEnv* env, jobject token, jmethodID getAttribute, jint i) { + return (jbyteArray) (*env)->CallObjectMethod(env, token, getAttribute, i); +} + +void Token_setPok(JNIEnv* env, jclass Token, jobject token, jbyteArray jba) { + jmethodID setPok = (*env)->GetMethodID(env, Token, "setPok", "([B)V"); + (*env)->CallVoidMethod(env, token, setPok, jba); +} #endif //ANDROID_ABE_NATIVE_LIB_H diff --git a/abe/src/main/java/com/codymlewis/abe/Functions.java b/abe/src/main/java/com/codymlewis/abe/Functions.java @@ -19,6 +19,11 @@ public class Functions { System.loadLibrary("native-lib"); } + public static native byte[] test(byte[] ba); + public static native int setup(Keychain keychain); public static native int issueToken(Keychain keychain, Token token); + public static native int proveKnowledge(Keychain keychain, Token token); + public static native int completeTokenIssue(Keychain keychain, Token token); + public static native boolean checkSigmas(Keychain keychain, Token token); } diff --git a/abe/src/main/java/com/codymlewis/abe/Keychain.java b/abe/src/main/java/com/codymlewis/abe/Keychain.java @@ -4,6 +4,7 @@ import java.util.ArrayList; public class Keychain { private String groupData; + private byte[] g; private byte[] x; private ArrayList<byte[]> y; private byte[] X; @@ -12,6 +13,7 @@ public class Keychain { public Keychain() { groupData = ""; + g = null; x = null; y = new ArrayList<>(); X = null; @@ -29,6 +31,10 @@ public class Keychain { this.groupData = groupData; } + public void setG(byte[] g) { + this.g = g; + } + public void addSecret(byte[] secret) { if (x == null) { x = secret; @@ -53,6 +59,10 @@ public class Keychain { return groupData; } + public byte[] getG() { + return g; + } + public byte[] getSecretX() { return x; } diff --git a/abe/src/main/java/com/codymlewis/abe/Token.java b/abe/src/main/java/com/codymlewis/abe/Token.java @@ -13,6 +13,8 @@ public class Token { private int n; private byte[] w; private ArrayList<byte[]> Adash; + private byte[] Tbar; + private byte[] pok; public Token() { userId = ""; @@ -24,6 +26,7 @@ public class Token { n = 0; w = null; Adash = new ArrayList<>(); + Tbar = null; } public Token(String userId, int n) { @@ -65,10 +68,6 @@ public class Token { public void setN(int n) { this.n = n; } -// -// public void setW(byte[] w) { -// this.w = w; -// } public void addAdash(byte[] adash) { if (w == null) { @@ -78,6 +77,14 @@ public class Token { } } + public void setTbar(byte[] tbar) { + Tbar = tbar; + } + + public void setPok(byte[] pok) { + this.pok = pok; + } + public String getUserId() { return userId; } @@ -117,4 +124,12 @@ public class Token { public byte[] getAdash(int i) { return Adash.get(i); } + + public byte[] getTbar() { + return Tbar; + } + + public byte[] getPok() { + return pok; + } } diff --git a/app/build.gradle b/app/build.gradle @@ -7,7 +7,8 @@ android { defaultConfig { applicationId "com.codymlewis.androidabe" - minSdkVersion 16 +// minSdkVersion 16 + minSdkVersion 26 targetSdkVersion 29 versionCode 1 versionName "1.0" diff --git a/app/src/main/java/com/codymlewis/androidabe/MainActivity.java b/app/src/main/java/com/codymlewis/androidabe/MainActivity.java @@ -19,6 +19,7 @@ public class MainActivity extends AppCompatActivity { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); + String attributes[] = new String[] {"a", "b", "c"}; TextView tv = findViewById(R.id.output_text); String groupParams = ""; try { @@ -27,9 +28,11 @@ public class MainActivity extends AppCompatActivity { tv.setText(getString(R.string.asset_io_error_message, ioe.getMessage())); } System.out.println("Loaded param file"); - Keychain kc = new Keychain(groupParams, 5); + Keychain kc = new Keychain(groupParams, attributes.length); Functions.setup(kc); String text = String.format("x = %s\n", Base64.getEncoder().encodeToString(kc.getSecretX())); + +// text += String.format("g = %s\n", Base64.getEncoder().encodeToString(kc.getG())); // for (int i = 0; i < kc.lenSecretY(); ++i) { // text += String.format("y_%d = %s\n", i, Base64.getEncoder().encodeToString(kc.getSecretY(i))); // } @@ -38,10 +41,21 @@ public class MainActivity extends AppCompatActivity { // text += String.format("Y_%d = %s\n", i, Base64.getEncoder().encodeToString(kc.getPublicY(i))); // } - Token token = new Token("Alice", 5); + Token token = new Token("Alice", attributes.length); + token.addAttributes(attributes); Functions.issueToken(kc, token); text += String.format("sigma1 = %s\n", Base64.getEncoder().encodeToString(token.getSigma1())); text += String.format("sigmabar1 = %s\n", Base64.getEncoder().encodeToString(token.getSigmabar1())); + Functions.proveKnowledge(kc, token); + text += String.format("Tbar = %s\n", Base64.getEncoder().encodeToString(token.getTbar())); + text += String.format("PoK = %s\n", Base64.getEncoder().encodeToString(token.getPok())); + Functions.completeTokenIssue(kc, token); + if (Functions.checkSigmas(kc, token)) { + text += "Sigmas successfully calculated\n"; + } else { + text += "Failed to calculate sigmas\n"; + } tv.setText(text); + } } diff --git a/wearapp/build.gradle b/wearapp/build.gradle @@ -50,7 +50,7 @@ dependencies { implementation 'androidx.legacy:legacy-support-v4:1.0.0' implementation 'androidx.recyclerview:recyclerview:1.1.0' implementation 'androidx.wear:wear:1.0.0' - compileOnly 'com.google.android.wearable:wearable:2.6.0' + compileOnly 'com.google.android.wearable:wearable:2.7.0' implementation project(':abe') }