From 94cbddb97da5cf307fe1ee5fd29f6f2b1161df66 Mon Sep 17 00:00:00 2001 From: Michael Preisach Date: Tue, 29 Sep 2020 09:44:10 +0000 Subject: [PATCH] added test for encoding and decoding --- common.c | 6 ++++-- common.h | 4 ++++ daa-test.c | 27 +++++++++++++++++++++------ ecdaa_test | Bin 27312 -> 31800 bytes 4 files changed, 29 insertions(+), 8 deletions(-) diff --git a/common.c b/common.c index 163cbfa..3fd8f48 100644 --- a/common.c +++ b/common.c @@ -48,7 +48,7 @@ void ecdaa_bintohex(const uint8_t *in_bin, char *out_hex, size_t inlen) { } } -void ecdaa_encode(const uint8_t *in_dec, char *out_enc, size_t inlen) { +int ecdaa_encode(const uint8_t *in_dec, char *out_enc, size_t inlen) { int outlen = 4 * ((inlen + 2) / 3); int i = 0; int j = 0; @@ -73,9 +73,10 @@ void ecdaa_encode(const uint8_t *in_dec, char *out_enc, size_t inlen) { default: break; } + return j; } -void ecdaa_decode(const uint8_t *in_enc, char *out_dec, size_t outlen) { +int ecdaa_decode(const char *in_enc, uint8_t *out_dec, size_t outlen) { int inlen = 4 * ((outlen + 2) / 3); int i = 0; int j = 0; @@ -92,4 +93,5 @@ void ecdaa_decode(const uint8_t *in_enc, char *out_dec, size_t outlen) { if (j < outlen) out_dec[j++] = (triple >> 8) & 0xFF; if (j < outlen) out_dec[j++] = triple & 0xFF; } + return i; } diff --git a/common.h b/common.h index 0d89807..b28108a 100644 --- a/common.h +++ b/common.h @@ -31,4 +31,8 @@ void ecdaa_hextobin(const char *in_hex, uint8_t *out_bin, size_t outlen); void ecdaa_bintohex(const uint8_t *in_bin, char *out_hex, size_t inlen); +int ecdaa_decode(const char *in_enc, uint8_t *out_dec, size_t outlen); + +int ecdaa_encode(const uint8_t *in_dec, char *out_enc, size_t inlen); + #endif //ECDAA_ISSUER_COMMON_H diff --git a/daa-test.c b/daa-test.c index b996858..54b89c0 100644 --- a/daa-test.c +++ b/daa-test.c @@ -178,7 +178,7 @@ int test2() { if(0 != ecdaa_signature_FP256BN_verify(&sig2, &ipk2.gpk, &revocations, msg, msg_len, bsn, bsn_len)) { printf("verify message failed\n"); - //return 1; + return 1; } strncpy(bsn, "test basename", 13); @@ -238,15 +238,30 @@ int test3() { } ecdaa_issuer_public_key_FP256BN_serialize(binbuf, &ipk); - ecdaa_bintohex(binbuf, current, ECDAA_ISSUER_PUBLIC_KEY_FP256BN_LENGTH); - + int numbytes = ecdaa_encode(binbuf, current, ECDAA_ISSUER_PUBLIC_KEY_FP256BN_LENGTH); + current = ¤t[numbytes]; - if(0 != ecdaa_issuer_public_key_FP256BN_deserialize_file(&ipk2, "ipktest.bin") || - 0 != ecdaa_issuer_secret_key_FP256BN_deserialize_file(&isk2, "isktest.bin")) { + bzero(binbuf,MAX_BUFSIZE); + ecdaa_issuer_secret_key_FP256BN_serialize(binbuf, &isk); + numbytes += ecdaa_encode(binbuf, current, ECDAA_ISSUER_SECRET_KEY_FP256BN_LENGTH); + //current = &buffer[numbytes]; + + printf("Encoded issuer key pair: %s\n%s\n", buffer, current); + + current = buffer; + int numbytes2 = ecdaa_decode(current, binbuf, ECDAA_ISSUER_PUBLIC_KEY_FP256BN_LENGTH); + int ret = ecdaa_issuer_public_key_FP256BN_deserialize(&ipk2, binbuf); + + current = &buffer[numbytes2]; + bzero(binbuf,MAX_BUFSIZE); + numbytes2 += ecdaa_decode(current, binbuf, ECDAA_ISSUER_SECRET_KEY_FP256BN_LENGTH); + ret += ecdaa_issuer_secret_key_FP256BN_deserialize(&isk2, binbuf); + if(0 != ret) { + printf("numbytes = %i, numbytes2 = %i\n", numbytes, numbytes2); printf("loading issuer key pair failed\n"); return 1; } - + ecdaa_rand(nonce, NONCE_SIZE); if(0 != ecdaa_member_key_pair_FP256BN_generate(&mpk, &msk, nonce, NONCE_SIZE, ecdaa_rand)) { printf("generate member key pair failed\n"); diff --git a/ecdaa_test b/ecdaa_test index 7e9888014163fe2dcabec20bcc011ef9f1ff0be1..f23a4d2d5df9102ea932afa4f4211f5f2990607b 100755 GIT binary patch literal 31800 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 delta 7925 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 pf@f+Pt^A^ZH(Ie*