1 /******************************************************************************
2 * NTRU Cryptography Reference Source Code
3 * Copyright (c) 2009-2013, by Security Innovation, Inc. All rights reserved.
5 * ntru_crypto_ntru_encrypt_key.c is a component of ntru-crypto.
7 * Copyright (C) 2009-2013 Security Innovation
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
23 *****************************************************************************/
25 /******************************************************************************
27 * File: ntru_crypto_ntru_encrypt_key.c
29 * Contents: Routines for exporting and importing public and private keys
32 *****************************************************************************/
38 #include "ntru_crypto_ntru_encrypt_key.h"
41 /* ntru_crypto_ntru_encrypt_key_parse
43 * Parses an NTRUEncrypt key blob.
44 * If the blob is not corrupt, returns packing types for public and private
45 * keys, a pointer to the parameter set, a pointer to the public key, and
46 * a pointer to the private key if it exists.
48 * Returns TRUE if successful.
49 * Returns FALSE if the blob is invalid.
53 ntru_crypto_ntru_encrypt_key_parse(
54 bool pubkey_parse
, /* in - if parsing pubkey
56 uint16_t key_blob_len
, /* in - no. octets in key
58 uint8_t const *key_blob
, /* in - pointer to key blob */
59 uint8_t *pubkey_pack_type
, /* out - addr for pubkey
61 uint8_t *privkey_pack_type
, /* out - addr for privkey
63 ntru_param_set_t
**params
, /* out - addr for ptr to
65 uint8_t const **pubkey
, /* out - addr for ptr to
67 uint8_t const **privkey
) /* out - addr for ptr to
72 /* parse key blob based on tag */
75 case NTRU_ENCRYPT_PUBKEY_TAG
:
79 case NTRU_ENCRYPT_PRIVKEY_DEFAULT_TAG
:
80 case NTRU_ENCRYPT_PRIVKEY_TRITS_TAG
:
81 case NTRU_ENCRYPT_PRIVKEY_INDICES_TAG
:
82 assert(privkey_pack_type
);
92 case NTRU_ENCRYPT_PUBKEY_TAG
:
93 case NTRU_ENCRYPT_PRIVKEY_DEFAULT_TAG
:
94 case NTRU_ENCRYPT_PRIVKEY_TRITS_TAG
:
95 case NTRU_ENCRYPT_PRIVKEY_INDICES_TAG
:
99 * byte 1: no. of octets in OID
101 * bytes 5- : packed pubkey
106 ntru_param_set_t
*p
= NULL
;
107 uint16_t pubkey_packed_len
;
109 /* check OID length and minimum blob length for tag and OID */
111 if ((key_blob_len
< 5) || (key_blob
[1] != 3))
114 /* get a pointer to the parameter set corresponding to the OID */
115 p
= ntru_param_set_get_by_oid(key_blob
+ 2);
121 /* check blob length and assign pointers to blob fields */
123 pubkey_packed_len
= (p
->N
* p
->q_bits
+ 7) / 8;
124 if (pubkey_parse
) { /* public-key parsing */
125 if (key_blob_len
!= 5 + pubkey_packed_len
)
128 *pubkey
= key_blob
+ 5;
130 } else { /* private-key parsing */
131 uint16_t privkey_packed_len
;
132 uint16_t privkey_packed_trits_len
= (p
->N
+ 4) / 5;
133 uint16_t privkey_packed_indices_len
;
136 /* check packing type for product-form private keys */
138 if (p
->is_product_form
&&
139 (tag
== NTRU_ENCRYPT_PRIVKEY_TRITS_TAG
))
142 /* set packed-key length for packed indices */
144 if (p
->is_product_form
)
145 dF
= (uint16_t)( (p
->dF_r
& 0xff) + /* df1 */
146 ((p
->dF_r
>> 8) & 0xff) + /* df2 */
147 ((p
->dF_r
>> 16) & 0xff)); /* df3 */
149 dF
= (uint16_t)p
->dF_r
;
150 privkey_packed_indices_len
= ((dF
<< 1) * p
->N_bits
+ 7) >> 3;
152 /* set private-key packing type if defaulted */
154 if (tag
== NTRU_ENCRYPT_PRIVKEY_DEFAULT_TAG
) {
155 if (p
->is_product_form
||
156 (privkey_packed_indices_len
<=
157 privkey_packed_trits_len
))
158 tag
= NTRU_ENCRYPT_PRIVKEY_INDICES_TAG
;
160 tag
= NTRU_ENCRYPT_PRIVKEY_TRITS_TAG
;
163 if (tag
== NTRU_ENCRYPT_PRIVKEY_TRITS_TAG
)
164 privkey_packed_len
= privkey_packed_trits_len
;
166 privkey_packed_len
= privkey_packed_indices_len
;
168 if (key_blob_len
!= 5 + pubkey_packed_len
+ privkey_packed_len
)
171 *pubkey
= key_blob
+ 5;
172 *privkey
= *pubkey
+ pubkey_packed_len
;
173 *privkey_pack_type
= (tag
== NTRU_ENCRYPT_PRIVKEY_TRITS_TAG
) ?
174 NTRU_ENCRYPT_KEY_PACKED_TRITS
:
175 NTRU_ENCRYPT_KEY_PACKED_INDICES
;
178 /* return parameter set pointer */
180 *pubkey_pack_type
= NTRU_ENCRYPT_KEY_PACKED_COEFFICIENTS
;
184 break; /* can't get here */
190 /* ntru_crypto_ntru_encrypt_key_get_blob_params
192 * Returns public and private key packing types and blob lengths given
193 * a packing format. For now, only a default packing format exists.
195 * Only public-key params may be returned by setting privkey_pack_type
196 * and privkey_blob_len to NULL.
200 ntru_crypto_ntru_encrypt_key_get_blob_params(
201 ntru_param_set_t
*params
, /* in - pointer to
204 uint8_t *pubkey_pack_type
, /* out - addr for pubkey
206 uint16_t *pubkey_blob_len
, /* out - addr for no. of
209 uint8_t *privkey_pack_type
, /* out - addr for privkey
211 uint16_t *privkey_blob_len
) /* out - addr for no. of
215 uint16_t pubkey_packed_len
= (params
->N
* params
->q_bits
+ 7) >> 3;
218 assert(pubkey_pack_type
);
219 assert(pubkey_blob_len
);
221 *pubkey_pack_type
= NTRU_ENCRYPT_KEY_PACKED_COEFFICIENTS
;
222 *pubkey_blob_len
= 5 + pubkey_packed_len
;
224 if (privkey_pack_type
&& privkey_blob_len
) {
225 uint16_t privkey_packed_trits_len
= (params
->N
+ 4) / 5;
226 uint16_t privkey_packed_indices_len
;
229 if (params
->is_product_form
)
230 dF
= (uint16_t)( (params
->dF_r
& 0xff) + /* df1 */
231 ((params
->dF_r
>> 8) & 0xff) + /* df2 */
232 ((params
->dF_r
>> 16) & 0xff)); /* df3 */
234 dF
= (uint16_t)params
->dF_r
;
235 privkey_packed_indices_len
= ((dF
<< 1) * params
->N_bits
+ 7) >> 3;
237 if (params
->is_product_form
||
238 (privkey_packed_indices_len
<= privkey_packed_trits_len
)) {
239 *privkey_pack_type
= NTRU_ENCRYPT_KEY_PACKED_INDICES
;
241 5 + pubkey_packed_len
+ privkey_packed_indices_len
;
243 *privkey_pack_type
= NTRU_ENCRYPT_KEY_PACKED_TRITS
;
245 5 + pubkey_packed_len
+ privkey_packed_trits_len
;
251 /* ntru_crypto_ntru_encrypt_key_create_pubkey_blob
253 * Returns a public key blob, packed according to the packing type provided.
257 ntru_crypto_ntru_encrypt_key_create_pubkey_blob(
258 ntru_param_set_t
*params
, /* in - pointer to
261 uint16_t const *pubkey
, /* in - pointer to the
264 uint8_t pubkey_pack_type
, /* out - pubkey packing
266 uint8_t *pubkey_blob
) /* out - addr for the
273 switch (pubkey_pack_type
) {
274 case NTRU_ENCRYPT_KEY_PACKED_COEFFICIENTS
:
275 *pubkey_blob
++ = NTRU_ENCRYPT_PUBKEY_TAG
;
276 *pubkey_blob
++ = (uint8_t)sizeof(params
->oid
);
277 memcpy(pubkey_blob
, params
->oid
, sizeof(params
->oid
));
278 pubkey_blob
+= sizeof(params
->oid
);
279 ntru_elements_2_octets(params
->N
, pubkey
, params
->q_bits
,
288 /* ntru_crypto_ntru_encrypt_key_create_privkey_blob
290 * Returns a private key blob, packed according to the packing type provided.
294 ntru_crypto_ntru_encrypt_key_create_privkey_blob(
295 ntru_param_set_t
*params
, /* in - pointer to
298 uint16_t const *pubkey
, /* in - pointer to the
301 uint16_t const *privkey
, /* in - pointer to the
304 uint8_t privkey_pack_type
, /* in - privkey packing
306 uint8_t *buf
, /* in - temp, N bytes */
307 uint8_t *privkey_blob
) /* out - addr for the
313 assert(privkey_blob
);
315 switch (privkey_pack_type
) {
316 case NTRU_ENCRYPT_KEY_PACKED_TRITS
:
317 case NTRU_ENCRYPT_KEY_PACKED_INDICES
:
319 /* format header and packed public key */
321 *privkey_blob
++ = NTRU_ENCRYPT_PRIVKEY_DEFAULT_TAG
;
322 *privkey_blob
++ = (uint8_t)sizeof(params
->oid
);
323 memcpy(privkey_blob
, params
->oid
, sizeof(params
->oid
));
324 privkey_blob
+= sizeof(params
->oid
);
325 ntru_elements_2_octets(params
->N
, pubkey
, params
->q_bits
,
327 privkey_blob
+= (params
->N
* params
->q_bits
+ 7) >> 3;
329 /* add packed private key */
331 if (privkey_pack_type
== NTRU_ENCRYPT_KEY_PACKED_TRITS
) {
332 ntru_indices_2_packed_trits(privkey
, (uint16_t)params
->dF_r
,
333 (uint16_t)params
->dF_r
,
334 params
->N
, buf
, privkey_blob
);
338 if (params
->is_product_form
) {
339 dF
= (params
->dF_r
& 0xff) +
340 ((params
->dF_r
>> 8) & 0xff) +
341 ((params
->dF_r
>> 16) & 0xff);
345 ntru_elements_2_octets((uint16_t)dF
<< 1, privkey
,
346 params
->N_bits
, privkey_blob
);