uint8_t ntru_gen_key_pair_single(const NtruEncParams *params, NtruEncPrivKey *priv, NtruEncPubKey *pub, NtruIntPoly *fq, NtruRandContext *rand_ctx) { uint16_t N = params->N; uint16_t q = params->q; uint16_t df1 = params->df1; #ifndef NTRU_AVOID_HAMMING_WT_PATENT uint16_t df2 = params->df2; uint16_t df3 = params->df3; #endif /* NTRU_AVOID_HAMMING_WT_PATENT */ if (q & (q-1)) /* check that modulus is a power of 2 */ return NTRU_ERR_INVALID_PARAM; /* choose a random f that is invertible mod q */ #ifndef NTRU_AVOID_HAMMING_WT_PATENT if (params->prod_flag) { NtruPrivPoly *t = &priv->t; t->prod_flag = 1; t->poly.prod.N = N; priv->q = q; for (;;) { /* choose random t, find the inverse of 3t+1 */ if (!ntru_rand_prod(N, df1, df2, df3, df3, &t->poly.prod, rand_ctx)) return NTRU_ERR_PRNG; if (ntru_invert(t, q-1, fq)) break; } } else #endif /* NTRU_AVOID_HAMMING_WT_PATENT */ { NtruPrivPoly *t = &priv->t; t->prod_flag = 0; priv->q = q; for (;;) { /* choose random t, find the inverse of 3t+1 */ if (!ntru_rand_tern(N, df1, df1, &t->poly.tern, rand_ctx)) return NTRU_ERR_PRNG; if (ntru_invert(t, q-1, fq)) break; } } /* choose a random g */ NtruPrivPoly g; uint8_t result = ntru_gen_g(params, &g, rand_ctx); if (result != NTRU_SUCCESS) return result; NtruIntPoly *h = &pub->h; if (!ntru_mult_priv(&g, fq, h, q-1)) return NTRU_ERR_INVALID_PARAM; ntru_mult_fac(h, 3); ntru_mod_mask(h, q-1); ntru_clear_priv(&g); pub->q = q; return NTRU_SUCCESS; }
uint8_t ntru_gen_key_pair(const NtruEncParams *params, NtruEncKeyPair *kp, NtruRandContext *rand_ctx) { uint16_t N = params->N; uint16_t q = params->q; uint16_t df1 = params->df1; #ifndef NTRU_AVOID_HAMMING_WT_PATENT uint16_t df2 = params->df2; uint16_t df3 = params->df3; #endif /* NTRU_AVOID_HAMMING_WT_PATENT */ NtruIntPoly fq; /* choose a random f that is invertible mod q */ #ifndef NTRU_AVOID_HAMMING_WT_PATENT if (params->prod_flag) { NtruPrivPoly *t = &kp->priv.t; t->prod_flag = 1; t->poly.prod.N = N; kp->priv.q = q; for (;;) { /* choose random t, find the inverse of 3t+1 */ if (!ntru_rand_prod(N, df1, df2, df3, df3, &t->poly.prod, rand_ctx)) return NTRU_ERR_PRNG; if (ntru_invert(t, q, &fq)) break; } } else #endif /* NTRU_AVOID_HAMMING_WT_PATENT */ { NtruPrivPoly *t = &kp->priv.t; t->prod_flag = 0; kp->priv.q = q; for (;;) { /* choose random t, find the inverse of 3t+1 */ if (!ntru_rand_tern(N, df1, df1, &t->poly.tern, rand_ctx)) return NTRU_ERR_PRNG; if (ntru_invert(t, q, &fq)) break; } } /* choose a random g that is invertible mod q */ NtruPrivPoly g; uint16_t dg = N / 3; for (;;) { #ifndef NTRU_AVOID_HAMMING_WT_PATENT if (params->prod_flag && !ntru_rand_prod(N, df1, df2, df3, df3, &g.poly.prod, rand_ctx)) return NTRU_ERR_PRNG; if (!params->prod_flag && !ntru_rand_tern(N, dg, dg, &g.poly.tern, rand_ctx)) return NTRU_ERR_PRNG; g.prod_flag = params->prod_flag; #else if (!ntru_rand_tern(N, dg, dg, &g.poly.tern, rand_ctx)) return NTRU_ERR_PRNG; g.prod_flag = 0; #endif /* NTRU_AVOID_HAMMING_WT_PATENT */ if (!NTRU_CHECK_INVERTIBILITY_G) break; NtruIntPoly gq; if (ntru_invert(&g, q, &gq)) break; } NtruIntPoly *h = &kp->pub.h; if (!ntru_mult_priv(&g, &fq, h, q)) return NTRU_ERR_PRNG; ntru_mult_fac(h, 3); ntru_mod(h, q); ntru_clear_priv(&g); ntru_clear_int(&fq); kp->pub.q = q; return NTRU_SUCCESS; }