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:
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')
}