androidabe

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

commit e1a336d0a5508f4f2f5141785c79988af4000b82
parent 7e85edd8a891d06023e526e67974805436060a02
Author: Cody Lewis <cody@codymlewis.com>
Date:   Fri, 29 May 2020 10:35:03 +1000

Got most of the sigma caculations working

Diffstat:
Mabe/src/main/cpp/native-lib.c | 228++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------
Mabe/src/main/cpp/native-lib.h | 57++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
Mabe/src/main/java/com/codymlewis/abe/Token.java | 21+++++++++++++++++++++
Mapp/src/main/java/com/codymlewis/androidabe/MainActivity.java | 6++++--
4 files changed, 283 insertions(+), 29 deletions(-)

diff --git a/abe/src/main/cpp/native-lib.c b/abe/src/main/cpp/native-lib.c @@ -90,8 +90,9 @@ int clear_elements(element_t* els, const size_t n) return 1; } +// TODO: check whether the hash functions belong to particular group // 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! +int hash_1(const unsigned char* buf, const size_t len, element_t e) // Remember to init e! { SHA256_CTX c; SHA256_Init(&c); @@ -137,23 +138,23 @@ Java_com_codymlewis_abe_Functions_setup( 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]; + element_t y; + element_t Y; jmethodID addSecret = (*env)->GetMethodID(env, Keychain, "addSecret", "([B)V"); jmethodID addPublic = (*env)->GetMethodID(env, Keychain, "addPublic", "([B)V"); 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"); + element_init_Zr(y, pairing); + element_random(y); + jbyteArray s = element_to_jbyteArray(env, pairing, y, "Zr"); (*env)->CallVoidMethod(env, keychain, addSecret, s); - element_init_G2(Y[i], pairing); - element_pp_pow_zn(Y[i], y[i], g_pp); - jbyteArray p = element_to_jbyteArray(env, pairing, Y[i], "G2"); + element_init_G2(Y, pairing); + element_pp_pow_zn(Y, y, g_pp); + jbyteArray p = element_to_jbyteArray(env, pairing, Y, "G2"); (*env)->CallVoidMethod(env, keychain, addPublic, p); + element_clear(y); + element_clear(Y); } - 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); @@ -173,13 +174,14 @@ Java_com_codymlewis_abe_Functions_issueToken( pairing_t pairing; init_pairing(env, &pairing, Keychain_getGroupData(env, Keychain, keychain)); - element_t h, hbar; + element_t h; element_init_G1(h, pairing); element_random(h); - Token_setSigma(env, Token, token, "setSigma1", element_to_jbyteArray(env, pairing, h, "Zr")); + Token_setSigma(env, Token, token, "setSigma1", element_to_jbyteArray(env, pairing, h, "G1")); + element_t hbar; element_init_G1(hbar, pairing); element_random(hbar); - Token_setSigma(env, Token, token, "setSigmabar1", element_to_jbyteArray(env, pairing, hbar, "Zr")); + Token_setSigma(env, Token, token, "setSigmabar1", element_to_jbyteArray(env, pairing, hbar, "G1")); pairing_clear(pairing); element_clear(h); @@ -187,6 +189,14 @@ Java_com_codymlewis_abe_Functions_issueToken( return 1; } +int calc_m_i(JNIEnv* env, jclass token, jmethodID getAttribute, int i, element_t H_1_a_i, element_t Adash_i, element_t m_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); + pbc_free(a_i); +} + JNIEXPORT jint JNICALL Java_com_codymlewis_abe_Functions_proveKnowledge( JNIEnv* env, @@ -244,21 +254,21 @@ Java_com_codymlewis_abe_Functions_proveKnowledge( element_t m_i; element_init_Zr(m_i, pairing); unsigned char* m_i_buf; - for (int i = 0; i < k; ++i) { + for (size_t i = 0; i < k + 1; ++i) { if (i == 0) { element_pow_zn(temp, h, Adash[0]); element_to_bytes(pok, temp); } else { + // TODO LOOKS like this might be off by one! // 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]); + calc_m_i(env, token, getAttribute, i - 1, H_1_a_i, Adash[i], m_i); + print_el(pairing, H_1_a_i, "Zr", "proveKnowledge", "H_1_a_i"); // set pok = pok & h^(m_i) - element_pow_zn(m_i, h, m_i); + element_pow_zn(temp, 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]; + element_to_bytes(m_i_buf, temp); + for (size_t j = 0; j < n; ++j) { + pok[j] = pok[j] & m_i_buf[j]; } pbc_free(m_i_buf); } @@ -276,6 +286,108 @@ Java_com_codymlewis_abe_Functions_proveKnowledge( return 1; } +int calc_sig_2( + JNIEnv* env, + jclass Keychain, + jobject keychain, + jclass Token, + jobject token, + pairing_t pairing, + const unsigned char* I, + element_t sig_2) +{ + element_t h; + element_init_G1(h, pairing); + element_from_jbyteArray(env, h, Token_getSigma(env, Token, token, "getSigma1")); + element_t x; + element_init_Zr(x, pairing); + element_from_jbyteArray(env, x, Keychain_getSecretX(env, Keychain, keychain)); + element_t temp_G1; + element_init_G1(temp_G1, pairing); + element_t temp_Zr; + element_init_Zr(temp_Zr, pairing); + element_t temp_y; + element_init_Zr(temp_y, pairing); + int k = Keychain_getK(env, Keychain, keychain); + + print_el(pairing, h, "G1", "checkSigmas", "h"); + + element_pow_zn(sig_2, h, x); // h^x + element_from_jbyteArray(env, temp_Zr, Token_getW(env, Token, token)); + element_from_jbyteArray(env, temp_y, Keychain_getSecretY(env, Keychain, keychain, 0)); + element_mul(temp_Zr, temp_Zr, temp_y); // w * y_0 + element_pow_zn(temp_G1, h, temp_Zr); // h^(w*y_0) + element_mul(sig_2, sig_2, temp_G1); // h^x * h^(w*y_0) + hash_1(I, strlen((char*) I), temp_Zr); + element_from_jbyteArray(env, temp_y, Keychain_getSecretY(env, Keychain, keychain, k + 1)); + element_mul(temp_Zr, temp_Zr, temp_y); // H_1(I) * y_(k+1) + element_pow_zn(temp_G1, h, temp_Zr); // h^(H_1(I) * y_(k+1)) + element_mul(sig_2, sig_2, temp_G1); // h^x * h^(w*y_0) * h^(H_1(I) * y_(k+1)) + + element_t H_1_a_i; + element_init_Zr(H_1_a_i, pairing); + jmethodID getAttribute = get_Token_getAttribute_ID(env, Token); + jmethodID getAdash = get_Token_getAdash_ID(env, Token); + for (size_t i = 0; i < k; ++i) { + // store m_i in temp_Zr + element_from_jbyteArray(env, temp_Zr, Token_getAdash(env, token, getAdash, i)); + calc_m_i(env, token, getAttribute, i, H_1_a_i, temp_Zr, temp_Zr); + element_from_jbyteArray(env, temp_y, Keychain_getSecretY(env, Keychain, keychain, i)); + element_mul(temp_Zr, temp_Zr, temp_y); // m_i * y_i + element_pow_zn(temp_G1, h, temp_Zr); // h^(m_i * y_i) + element_mul(sig_2, sig_2, temp_G1); // h^x * h^(w*y_0) * h^(H_1(I) * y_(k+1)) * Prod(h^(m_i * y_i)) + } + element_clear(H_1_a_i); + + element_clear(temp_G1); + element_clear(temp_Zr); + element_clear(temp_y); + element_clear(x); + element_clear(h); + return 1; +} + +int calc_sigbar_2( + JNIEnv* env, + jclass Keychain, + jobject keychain, + jclass Token, + jobject token, + pairing_t pairing, + element_t sigbar_2) +{ + element_t h; + element_init_G1(h, pairing); + element_from_jbyteArray(env, h, Token_getSigma(env, Token, token, "getSigma1")); + element_t x; + element_init_Zr(x, pairing); + element_from_jbyteArray(env, x, Keychain_getSecretX(env, Keychain, keychain)); + element_t temp_G1; + element_init_G1(temp_G1, pairing); + element_t temp_Zr; + element_init_Zr(temp_Zr, pairing); + element_t temp_y; + element_init_Zr(temp_y, pairing); + + element_pow_zn(sigbar_2, h, x); + element_from_jbyteArray(env, temp_G1, Token_getTbar(env, Token, token)); + element_from_jbyteArray(env, temp_y, Keychain_getSecretY(env, Keychain, keychain, 0)); + element_pow_zn(temp_G1, temp_G1, temp_y); // Tbar^y_0 + element_mul(sigbar_2, sigbar_2, temp_G1); // h^x Tbar^y_0 + element_from_jbyteArray(env, temp_Zr, Token_getMr(env, Token, token)); + element_pow_zn(temp_G1, h, temp_Zr); // h^m_r + element_mul(sigbar_2, sigbar_2, temp_G1); // h^x * Tbar^y_0 * h^m_r + element_from_jbyteArray(env, temp_y, Keychain_getSecretY(env, Keychain, keychain, 1)); + element_mul(sigbar_2, sigbar_2, temp_y); // h^x * Tbar^y_0 * h^m_r * y_1 + + element_clear(temp_G1); + element_clear(temp_Zr); + element_clear(temp_y); + element_clear(x); + element_clear(h); + return 1; +} + JNIEXPORT jint JNICALL Java_com_codymlewis_abe_Functions_completeTokenIssue( JNIEnv* env, @@ -288,11 +400,37 @@ Java_com_codymlewis_abe_Functions_completeTokenIssue( pairing_t pairing; init_pairing(env, &pairing, Keychain_getGroupData(env, Keychain, keychain)); - // TODO check attributes and pok + // TODO check attributes and pok, fix time char I[64]; sprintf(I, "%lf%d", pbc_get_time(), Token_getN(env, Token, token)); - + Token_setI(env, Token, token, buffer_to_jbyteArray(env, (unsigned char*) I, sizeof(I) / sizeof(I[0]))); + __android_log_print(ANDROID_LOG_DEBUG, "completeTokenIssue", "I = %s", (unsigned char*) I); + + element_t sig_2; + element_init_G1(sig_2, pairing); + calc_sig_2(env, Keychain, keychain, Token, token, pairing, (unsigned char*) I, sig_2); + Token_setSigma(env, Token, token, "setSigma2", element_to_jbyteArray(env, pairing, sig_2, "G1")); + element_t m_r; + element_init_Zr(m_r, pairing); + element_random(m_r); + Token_setSigma(env, Token, token, "setMr", element_to_jbyteArray(env, pairing, m_r, "Zr")); + element_t sigbar_2; + element_init_G1(sigbar_2, pairing); + calc_sigbar_2(env, Keychain, keychain, Token, token, pairing, sigbar_2); + Token_setSigma(env, Token, token, "setSigmabar2", element_to_jbyteArray(env, pairing, sigbar_2, "G1")); + +// print_el(pairing, sig_2, "G1", "completeTokenIssue", "calced"); +// element_t token_sig_2; +// element_init_G1(token_sig_2, pairing); +// element_from_jbyteArray(env, token_sig_2, Token_getSigma(env, Token, token, "getSigma2")); +// print_el(pairing, sig_2, "G1", "completeTokenIssue", "sigma"); +// element_clear(token_sig_2); +// __android_log_print(ANDROID_LOG_DEBUG, "completeTokenIssue", "cmp = %d", element_cmp(sig_2, token_sig_2)); + + element_clear(m_r); + element_clear(sigbar_2); + element_clear(sig_2); pairing_clear(pairing); return 1; } @@ -304,6 +442,44 @@ Java_com_codymlewis_abe_Functions_checkSigmas( jobject keychain, jobject token) { - // TODO check that the sigmas calculate correctly, particularly the 2 ones - return 1; + // TODO check that the 1 sigmas calculate correctly + int ret_val = 0; + jclass Keychain = get_Keychain(env); + jclass Token = get_Token(env); + pairing_t pairing; + init_pairing(env, &pairing, Keychain_getGroupData(env, Keychain, keychain)); + unsigned char* I = jbyteArray_to_buffer(env, Token_getI(env, Token, token)); + __android_log_print(ANDROID_LOG_DEBUG, "checkSigmas", "I = %s", I); + + element_t sig_2; + element_init_G1(sig_2, pairing); +// calc_sig_2(env, Keychain, keychain, Token, token, pairing, I, sig_2); + element_from_jbyteArray(env, sig_2, Token_getSigma(env, Token, token, "getSigma2")); + element_t token_sig_2; + element_init_G1(token_sig_2, pairing); + element_from_jbyteArray(env, token_sig_2, Token_getSigma(env, Token, token, "getSigma2")); + __android_log_print(ANDROID_LOG_DEBUG, "checkSigmas", "before check 1"); + +// print_el(pairing, sig_2, "G1", "checkSigmas", "calced"); +// print_el(pairing, token_sig_2, "G1", "checkSigmas", "sigma"); + + if (!element_cmp(sig_2, token_sig_2)) { + element_t sigbar_2; + element_init_G1(sigbar_2, pairing); + calc_sigbar_2(env, Keychain, keychain, Token, token, pairing, sigbar_2); + element_t token_sigbar_2; + element_init_G1(token_sigbar_2, pairing); + element_from_jbyteArray(env, token_sigbar_2, Token_getSigma(env, Token, token, "getSigmabar2")); + + if (!element_cmp(sigbar_2, token_sigbar_2)) { + ret_val = 1; + } + element_clear(sigbar_2); + element_clear(token_sigbar_2); + } + + element_clear(sig_2); + element_clear(token_sig_2); + pairing_clear(pairing); + return (jboolean) ret_val; } \ No newline at end of file diff --git a/abe/src/main/cpp/native-lib.h b/abe/src/main/cpp/native-lib.h @@ -71,7 +71,7 @@ int clear_elements(element_t* els, const size_t n); * @param e Element to put the resulting hash into * @return 1 on completion */ -int hash_1(unsigned char* buf, const size_t len, element_t e); +int hash_1(const 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 @@ -108,6 +108,16 @@ jbyteArray Keychain_getG(JNIEnv* env, jclass Keychain, jobject keychain) { return (jbyteArray) (*env)->CallObjectMethod(env, keychain, getG); } +jbyteArray Keychain_getSecretX(JNIEnv* env, jclass Keychain, jobject keychain) { + jmethodID getSecretX = (*env)->GetMethodID(env, Keychain, "getSecretX", "()[B"); + return (jbyteArray) (*env)->CallObjectMethod(env, keychain, getSecretX); +} + +jbyteArray Keychain_getSecretY(JNIEnv* env, jclass Keychain, jobject keychain, const jint i) { + jmethodID getSecretY = (*env)->GetMethodID(env, Keychain, "getSecretY", "(I)[B"); + return (jbyteArray) (*env)->CallObjectMethod(env, keychain, getSecretY, i); +} + // Token Java related functions jclass get_Token(JNIEnv* env) { return (*env)->FindClass(env, "com/codymlewis/abe/Token"); @@ -141,11 +151,24 @@ void Token_addAdash(JNIEnv* env, jobject token, jmethodID addAdash, jbyteArray j (*env)->CallVoidMethod(env, token, addAdash, jba); } +jmethodID get_Token_getAdash_ID(JNIEnv* env, jclass Token) { + return (*env)->GetMethodID(env, Token, "getAdash", "(I)[B"); +} + +jbyteArray Token_getAdash(JNIEnv* env, jobject token, jmethodID getAdash, const jint i) { + return (jbyteArray) (*env)->CallObjectMethod(env, token, getAdash, i); +} + 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); } +jbyteArray Token_getTbar(JNIEnv* env, jclass Token, jobject token) { + jmethodID getTbar = (*env)->GetMethodID(env, Token, "getTbar", "()[B"); + return (jbyteArray) (*env)->CallObjectMethod(env, token, getTbar); +} + jmethodID get_Token_getAttribute_ID(JNIEnv* env, jclass Token) { return (*env)->GetMethodID(env, Token, "getAttribute", "(I)[B"); } @@ -159,4 +182,36 @@ void Token_setPok(JNIEnv* env, jclass Token, jobject token, jbyteArray jba) { (*env)->CallVoidMethod(env, token, setPok, jba); } +void Token_setI(JNIEnv* env, jclass Token, jobject token, jbyteArray jba) { + jmethodID setI = (*env)->GetMethodID(env, Token, "setI", "([B)V"); + (*env)->CallVoidMethod(env, token, setI, jba); +} + +jbyteArray Token_getI(JNIEnv* env, jclass Token, jobject token) { + jmethodID getI = (*env)->GetMethodID(env, Token, "getI", "()[B"); + return (jbyteArray) (*env)->CallObjectMethod(env, token, getI); +} + +jbyteArray Token_getW(JNIEnv* env, jclass Token, jobject token) { + jmethodID getW = (*env)->GetMethodID(env, Token, "getW", "()[B"); + return (jbyteArray) (*env)->CallObjectMethod(env, token, getW); +} + +jbyteArray Token_getMr(JNIEnv* env, jclass Token, jobject token) { + jmethodID getMr = (*env)->GetMethodID(env, Token, "getMr", "()[B"); + return (jbyteArray) (*env)->CallObjectMethod(env, token, getMr); +} + + + +void print_el(pairing_t pairing, element_t el, const char* group, const char* fun_name, const char* var_name) { + size_t n = (size_t) pairing_length_bytes(pairing, group); + unsigned char* buf = (unsigned char*) pbc_malloc(n); + element_to_bytes(buf, el); + for (int i = 0; i < n; ++i) { + __android_log_print(ANDROID_LOG_DEBUG, fun_name, "%s[%d] = %x", var_name, i, buf[i]); + } + pbc_free(buf); +} + #endif //ANDROID_ABE_NATIVE_LIB_H diff --git a/abe/src/main/java/com/codymlewis/abe/Token.java b/abe/src/main/java/com/codymlewis/abe/Token.java @@ -15,6 +15,8 @@ public class Token { private ArrayList<byte[]> Adash; private byte[] Tbar; private byte[] pok; + private byte[] I; + private byte[] Mr; public Token() { userId = ""; @@ -27,6 +29,9 @@ public class Token { w = null; Adash = new ArrayList<>(); Tbar = null; + pok = null; + I = null; + Mr = null; } public Token(String userId, int n) { @@ -85,6 +90,14 @@ public class Token { this.pok = pok; } + public void setI(byte[] i) { + I = i; + } + + public void setMr(byte[] mr) { + Mr = mr; + } + public String getUserId() { return userId; } @@ -132,4 +145,12 @@ public class Token { public byte[] getPok() { return pok; } + + public byte[] getI() { + return I; + } + + public byte[] getMr() { + return Mr; + } } diff --git a/app/src/main/java/com/codymlewis/androidabe/MainActivity.java b/app/src/main/java/com/codymlewis/androidabe/MainActivity.java @@ -19,7 +19,7 @@ public class MainActivity extends AppCompatActivity { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); - String attributes[] = new String[] {"a", "b", "c"}; + String[] attributes = new String[] {"a", "b", "c"}; TextView tv = findViewById(R.id.output_text); String groupParams = ""; try { @@ -27,7 +27,6 @@ public class MainActivity extends AppCompatActivity { } catch (IOException ioe) { tv.setText(getString(R.string.asset_io_error_message, ioe.getMessage())); } - System.out.println("Loaded param file"); Keychain kc = new Keychain(groupParams, attributes.length); Functions.setup(kc); String text = String.format("x = %s\n", Base64.getEncoder().encodeToString(kc.getSecretX())); @@ -50,6 +49,9 @@ public class MainActivity extends AppCompatActivity { 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); + text += String.format("sigma2 = %s\n", Base64.getEncoder().encodeToString(token.getSigma2())); +// text += String.format("Mr = %s\n", Base64.getEncoder().encodeToString(token.getMr())); +// text += String.format("sigmabar2 = %s\n", Base64.getEncoder().encodeToString(token.getSigmabar2())); if (Functions.checkSigmas(kc, token)) { text += "Sigmas successfully calculated\n"; } else {