d0427982bc03aab3b618af21ae7d95e50572d41e
[strongswan.git] / src / libstrongswan / plugins / ntru / ntru_crypto / ntru_crypto_ntru_mgftp1.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_mgftp1.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_mgftp1.c
28 *
29 * Contents: Routines implementing MGF-TP-1.
30 *
31 *****************************************************************************/
32
33
34 #include <stdlib.h>
35 #include <string.h>
36 #include "ntru_crypto_ntru_mgftp1.h"
37 #include "ntru_crypto_ntru_convert.h"
38
39 #include "ntru_mgf1.h"
40
41 /* ntru_mgftp1
42 *
43 * Implements a mask-generation function for trinary polynomials,
44 * MGF-TP-1, generating an arbitrary number of octets based on hashing
45 * a digest-length string concatenated with a 4-octet counter. From
46 * these octets, N trits are derived.
47 *
48 * The state (string and counter) is initialized when a seed is present.
49 *
50 * Returns NTRU_OK if successful.
51 * Returns NTRU_MGF1_FAIL if the MGF1 mask generator function fails
52 *
53 */
54
55 uint32_t
56 ntru_mgftp1(
57 hash_algorithm_t hash_algid, /* in - hash alg ID for
58 MGF-TP-1 */
59 uint8_t min_calls, /* in - minimum no. of hash
60 calls */
61 uint16_t seed_len, /* in - no. of octets in seed */
62 uint8_t *seed, /* in - pointer to seed */
63 uint8_t *buf, /* in - pointer to working
64 buffer */
65 uint16_t num_trits_needed, /* in - no. of trits in mask */
66 uint8_t *mask) /* out - address for mask trits */
67 {
68 uint8_t md_len;
69 uint8_t *octets;
70 uint16_t octets_available;
71 ntru_mgf1_t *mgf1;
72
73 /* generate minimum MGF1 output */
74 mgf1 = ntru_mgf1_create(hash_algid, chunk_create(seed, seed_len), TRUE);
75 if (!mgf1)
76 {
77 return NTRU_MGF1_FAIL;
78 }
79 md_len = mgf1->get_hash_size(mgf1);
80 octets = buf;
81 octets_available = min_calls * md_len;
82
83 DBG2(DBG_LIB, "MGF1 generates %u octets", octets_available);
84 if (!mgf1->get_mask(mgf1, octets_available, octets))
85 {
86 mgf1->destroy(mgf1);
87 return NTRU_MGF1_FAIL;
88 }
89
90 /* get trits for mask */
91 while (num_trits_needed >= 5)
92 {
93 /* get another octet and convert it to 5 trits */
94 if (octets_available == 0)
95 {
96 octets = buf;
97 octets_available = md_len;
98
99 DBG2(DBG_LIB, "MGF1 generates another %u octets", octets_available);
100 if (!mgf1->get_mask(mgf1, octets_available, octets))
101 {
102 mgf1->destroy(mgf1);
103 return NTRU_MGF1_FAIL;
104 }
105 }
106
107 if (*octets < 243)
108 {
109 ntru_octet_2_trits(*octets, mask);
110 mask += 5;
111 num_trits_needed -= 5;
112 }
113 octets++;
114 --octets_available;
115 }
116
117 /* get any remaining trits */
118 while (num_trits_needed)
119 {
120 uint8_t trits[5];
121
122 /* get another octet and convert it to remaining trits */
123 if (octets_available == 0)
124 {
125 octets = buf;
126 octets_available = md_len;
127
128 DBG2(DBG_LIB, "MGF1 generates another %u octets", octets_available);
129 if (!mgf1->get_mask(mgf1, octets_available, octets))
130 {
131 mgf1->destroy(mgf1);
132 return NTRU_MGF1_FAIL;
133 }
134 }
135 if (*octets < 243)
136 {
137 ntru_octet_2_trits(*octets, trits);
138 memcpy(mask, trits, num_trits_needed);
139 num_trits_needed = 0;
140 }
141 else
142 {
143 octets++;
144 --octets_available;
145 }
146 }
147 mgf1->destroy(mgf1);
148
149 return NTRU_OK;
150 }
151
152