Implemented ntru_private_key class
[strongswan.git] / src / libstrongswan / plugins / ntru / ntru_crypto / ntru_crypto_ntru_encrypt_key.c
1 /******************************************************************************
2 * NTRU Cryptography Reference Source Code
3 * Copyright (c) 2009-2013, by Security Innovation, Inc. All rights reserved.
4 *
5 * ntru_crypto_ntru_encrypt_key.c is a component of ntru-crypto.
6 *
7 * Copyright (C) 2009-2013 Security Innovation
8 *
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.
13 *
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.
18 *
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.
22 *
23 *****************************************************************************/
24
25 /******************************************************************************
26 *
27 * File: ntru_crypto_ntru_encrypt_key.c
28 *
29 * Contents: Routines for exporting and importing public and private keys
30 * for NTRUEncrypt.
31 *
32 *****************************************************************************/
33
34
35 #include <stdlib.h>
36 #include <string.h>
37 #include <assert.h>
38 #include "ntru_crypto_ntru_encrypt_key.h"
39
40
41 /* ntru_crypto_ntru_encrypt_key_parse
42 *
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.
47 *
48 * Returns TRUE if successful.
49 * Returns FALSE if the blob is invalid.
50 */
51
52 bool
53 ntru_crypto_ntru_encrypt_key_parse(
54 bool pubkey_parse, /* in - if parsing pubkey
55 blob */
56 uint16_t key_blob_len, /* in - no. octets in key
57 blob */
58 uint8_t const *key_blob, /* in - pointer to key blob */
59 uint8_t *pubkey_pack_type, /* out - addr for pubkey
60 packing type */
61 uint8_t *privkey_pack_type, /* out - addr for privkey
62 packing type */
63 ntru_param_set_t **params, /* out - addr for ptr to
64 parameter set */
65 uint8_t const **pubkey, /* out - addr for ptr to
66 packed pubkey */
67 uint8_t const **privkey) /* out - addr for ptr to
68 packed privkey */
69 {
70 uint8_t tag;
71
72 /* parse key blob based on tag */
73 tag = key_blob[0];
74 switch (tag) {
75 case NTRU_PUBKEY_TAG:
76 if (!pubkey_parse)
77 return FALSE;
78 break;
79 case NTRU_PRIVKEY_DEFAULT_TAG:
80 case NTRU_PRIVKEY_TRITS_TAG:
81 case NTRU_PRIVKEY_INDICES_TAG:
82 assert(privkey_pack_type);
83 assert(privkey);
84 if (pubkey_parse)
85 return FALSE;
86 break;
87 default:
88 return FALSE;
89 }
90
91 switch (tag) {
92 case NTRU_PUBKEY_TAG:
93 case NTRU_PRIVKEY_DEFAULT_TAG:
94 case NTRU_PRIVKEY_TRITS_TAG:
95 case NTRU_PRIVKEY_INDICES_TAG:
96
97 /* Version 0:
98 * byte 0: tag
99 * byte 1: no. of octets in OID
100 * bytes 2-4: OID
101 * bytes 5- : packed pubkey
102 * [packed privkey]
103 */
104
105 {
106 ntru_param_set_t *p = NULL;
107 uint16_t pubkey_packed_len;
108
109 /* check OID length and minimum blob length for tag and OID */
110
111 if ((key_blob_len < 5) || (key_blob[1] != 3))
112 return FALSE;
113
114 /* get a pointer to the parameter set corresponding to the OID */
115 p = ntru_param_set_get_by_oid(key_blob + 2);
116 if (!p)
117 {
118 return FALSE;
119 }
120
121 /* check blob length and assign pointers to blob fields */
122
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)
126 return FALSE;
127
128 *pubkey = key_blob + 5;
129
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;
134 uint16_t dF;
135
136 /* check packing type for product-form private keys */
137
138 if (p->is_product_form &&
139 (tag == NTRU_PRIVKEY_TRITS_TAG))
140 return FALSE;
141
142 /* set packed-key length for packed indices */
143
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 */
148 else
149 dF = (uint16_t)p->dF_r;
150 privkey_packed_indices_len = ((dF << 1) * p->N_bits + 7) >> 3;
151
152 /* set private-key packing type if defaulted */
153
154 if (tag == NTRU_PRIVKEY_DEFAULT_TAG) {
155 if (p->is_product_form ||
156 (privkey_packed_indices_len <=
157 privkey_packed_trits_len))
158 tag = NTRU_PRIVKEY_INDICES_TAG;
159 else
160 tag = NTRU_PRIVKEY_TRITS_TAG;
161 }
162
163 if (tag == NTRU_PRIVKEY_TRITS_TAG)
164 privkey_packed_len = privkey_packed_trits_len;
165 else
166 privkey_packed_len = privkey_packed_indices_len;
167
168 if (key_blob_len != 5 + pubkey_packed_len + privkey_packed_len)
169 return FALSE;
170
171 *pubkey = key_blob + 5;
172 *privkey = *pubkey + pubkey_packed_len;
173 *privkey_pack_type = (tag == NTRU_PRIVKEY_TRITS_TAG) ?
174 NTRU_KEY_PACKED_TRITS :
175 NTRU_KEY_PACKED_INDICES;
176 }
177
178 /* return parameter set pointer */
179
180 *pubkey_pack_type = NTRU_KEY_PACKED_COEFFICIENTS;
181 *params = p;
182 }
183 default:
184 break; /* can't get here */
185 }
186 return TRUE;
187 }