Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Identical Code Returning NTRU_ERR_INVALID_PARAM on iOS #42

Open
vpalazzo opened this issue Oct 5, 2018 · 4 comments
Open

Identical Code Returning NTRU_ERR_INVALID_PARAM on iOS #42

vpalazzo opened this issue Oct 5, 2018 · 4 comments

Comments

@vpalazzo
Copy link

vpalazzo commented Oct 5, 2018

I have the identical code, shown below, successfully encrypting messages on macOS, yet return NTRU_ERR_INVALID_PARAMS on iOS.

struct NtruEncParams params = NTRU_DEFAULT_PARAMS_256_BITS;
struct sockaddr_in si_other;
int s = 0;
int slen = sizeof(si_other);
char buf[BUFLEN];
char contact_oid[OID_SIZE] = { '\0' };

char message[BUFLEN * 4] = { '\0' };
char contact_public_key_string[BUFLEN] = { '\0' };
uint8_t digest[DIGEST_LENGTH] = { '\0' };
uint8_t pub_arr[ntru_pub_len(&params)];
char **tokens = NULL;
NtruRandGen rng_def = NTRU_RNG_DEFAULT;
NtruRandContext rand_ctx_def;

/* Hash password with SHA256 */
ntru_sha256(password, strlen(password), digest);

db_man_get_contacts_oid(contact_db_id, contact_oid);

if (!(strlen(contact_oid) > 0))
{
    fprintf(stderr, "That contact db_id does not exist in the "\
            "database!\n\n");
    return;
}

db_man_get_contacts_public_key(contact_db_id,
                               contact_public_key_string);

tokens = str_split(contact_public_key_string, '-');

if (tokens)
{
    int i;
    for (i = 0; *(tokens + i); i++)
    {
        free(*(tokens + i));
        pub_arr[i] = atoi( *(tokens + i));
    }
    printf("\n");
    free(tokens);
    
    /* import key from uint8_t array */
    NtruEncPubKey pub;
    ntru_import_pub(pub_arr, &pub);
    
    /* encryption */
    if (ntru_rand_init(&rand_ctx_def, &rng_def) != NTRU_SUCCESS)
    {
        printf("rng fail\n");
        return;
    }
    
    printf("Enc length: %u", ntru_enc_len(&params));
    uint8_t enc[ntru_enc_len(&params)];
    int err_code = 0;
    
    if ((err_code = ntru_encrypt(usr_msg, strlen(usr_msg), &pub, &params,
                     &rand_ctx_def, enc)) != NTRU_SUCCESS)
    {
        printf("encrypt fail: %u\n", err_code);
        return;
    }
@vpalazzo
Copy link
Author

vpalazzo commented Oct 5, 2018

I've traced the issue down to the following function/ statement:

uint8_t ntru_mult_prod(NtruIntPoly *a, NtruProdPoly *b, NtruIntPoly *c, uint16_t mod_mask) {
uint16_t N = a->N;
if (N != b->N) // This always equals false on iOS, why?....
    return 0;
c->N = N;
memset(&c->coeffs, 0, N * sizeof c->coeffs[0]);

NtruIntPoly temp;
ntru_mult_tern(a, &b->f1, &temp, mod_mask);
ntru_mult_tern(&temp, &b->f2, c, mod_mask);
NtruIntPoly f3a;
ntru_mult_tern(a, &b->f3, &f3a, mod_mask);
ntru_add(c, &f3a);

ntru_mod_mask(c, mod_mask);
return 1;
}

@vpalazzo
Copy link
Author

vpalazzo commented Oct 5, 2018

I have the entire project compiling in Xcode, I can supply the project file if need be.

@vpalazzo
Copy link
Author

vpalazzo commented Oct 5, 2018

Here is the exact point of failure within the 'encrypt' function.

uint8_t ntru_encrypt(uint8_t *msg, uint16_t msg_len, NtruEncPubKey *pub, const NtruEncParams     *params, NtruRandContext *rand_ctx, uint8_t *enc) {
ntru_set_optimized_impl();

uint16_t N = params->N;
uint16_t q = params->q;
uint16_t db = params->db;
uint16_t max_len_bytes = ntru_max_msg_len(params);
uint16_t dm0 = params->dm0;

if (q & (q-1))   /* check that modulus is a power of 2 */
    return NTRU_ERR_INVALID_PARAM;
if (max_len_bytes > 255)
    return NTRU_ERR_INVALID_MAX_LEN;
if (msg_len > max_len_bytes)
    return NTRU_ERR_MSG_TOO_LONG;

for (;;) {
    /* M = b|octL|msg|p0 */
    uint8_t b[db/8];
    if (ntru_rand_generate(b, db/8, rand_ctx) != NTRU_SUCCESS)
        return NTRU_ERR_PRNG;

    uint16_t M_len = db/8 + 1 + max_len_bytes + 1;
    uint8_t M[M_len];
    memcpy(&M, &b, db/8);
    uint8_t *M_head = (uint8_t*)&M + db/8;
    *M_head = msg_len;
    M_head++;
    memcpy(M_head, msg, msg_len);
    M_head += msg_len;
    memset(M_head, 0, max_len_bytes+1-msg_len);

    NtruIntPoly mtrin;
    ntru_from_sves((uint8_t*)&M, M_len, N, &mtrin);

    uint16_t blen = params->db / 8;
    uint16_t sdata_len = sizeof(params->oid) + msg_len + blen + blen;
    uint8_t sdata[sdata_len];
    ntru_get_seed(msg, msg_len, &pub->h, (uint8_t*)&b, params, (uint8_t*)&sdata);

    NtruIntPoly R;
    NtruPrivPoly r;
    ntru_gen_blind_poly((uint8_t*)&sdata, sdata_len, params, &r);
    if (!ntru_mult_priv(&r, &pub->h, &R, q-1)) // Here is the point of failure
        return NTRU_ERR_INVALID_PARAM;
    uint16_t oR4_len = (N*2+7) / 8;
    uint8_t oR4[oR4_len];
    ntru_to_arr4(&R, (uint8_t*)&oR4);
    NtruIntPoly mask;
    ntru_MGF((uint8_t*)&oR4, oR4_len, params, &mask);
    ntru_add(&mtrin, &mask);

    ntru_mod3(&mtrin);

    if (!ntru_check_rep_weight(&mtrin, dm0))
        continue;

    ntru_add(&R, &mtrin);
    ntru_to_arr(&R, q, enc);
    return NTRU_SUCCESS;
}
}

@AlekseiSazhnov
Copy link

Hey @vpalazzo!
I wanted to see how the implementation works for iOS but unable to integrate it with the project so far. Do you mind sharing your implementation for iOS?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants