Annotation of embedaddon/strongswan/src/libstrongswan/plugins/newhope/newhope_noise.c, revision 1.1.1.1
1.1 misho 1: /*
2: * Copyright (C) 2016 Andreas Steffen
3: * HSR Hochschule fuer Technik Rapperswil
4: *
5: * Based on public domain code by Erdem Alkim, Léo Ducas, Thomas Pöppelmann,
6: * and Peter Schwabe.
7: *
8: * This program is free software; you can redistribute it and/or modify it
9: * under the terms of the GNU General Public License as published by the
10: * Free Software Foundation; either version 2 of the License, or (at your
11: * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
12: *
13: * This program is distributed in the hope that it will be useful, but
14: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16: * for more details.
17: */
18:
19: #include "newhope_noise.h"
20:
21: typedef struct private_newhope_noise_t private_newhope_noise_t;
22:
23: static const int seed_len = 32; /* 256 bits */
24: static const int nonce_len = 12; /* 96 bits */
25:
26: /**
27: * Private data of an newhope_noise_t object.
28: */
29: struct private_newhope_noise_t {
30:
31: /**
32: * Public newhope_noise_t interface.
33: */
34: newhope_noise_t public;
35:
36: /**
37: * 256 bit seed and 96 bit nonce (44 bytes)
38: */
39: chunk_t seed;
40:
41: /**
42: * ChaCha20 stream
43: */
44: xof_t *xof;
45:
46: };
47:
48: METHOD(newhope_noise_t, get_uniform_bytes, uint8_t*,
49: private_newhope_noise_t *this, uint8_t nonce, uint16_t n)
50: {
51: uint8_t *bytes;
52:
53: this->seed.ptr[seed_len] = nonce;
54: if (!this->xof->set_seed(this->xof, this->seed))
55: {
56: DBG1(DBG_LIB, "could not set seed of CHACHA20 XOF");
57: return NULL;
58: }
59:
60: /* allocate dynamic memory for the noise polynomial */
61: bytes = (uint8_t*)malloc(n);
62:
63: if (!this->xof->get_bytes(this->xof, n, bytes))
64: {
65: DBG1(DBG_LIB, "could not get bytes from SHAKE128 XOF");
66: free(bytes);
67: return NULL;
68: }
69:
70: return bytes;
71: }
72:
73: METHOD(newhope_noise_t, get_binomial_words, uint32_t*,
74: private_newhope_noise_t *this, uint8_t nonce, uint16_t n, uint16_t q)
75: {
76: uint32_t *np, a, b, d, t;
77: uint8_t x[4];
78: int i = 0, j;
79:
80: this->seed.ptr[seed_len] = nonce;
81: if (!this->xof->set_seed(this->xof, this->seed))
82: {
83: DBG1(DBG_LIB, "could not set seed of CHACHA20 XOF");
84: return NULL;
85: }
86:
87: /* allocate dynamic memory for the noise polynomial */
88: np = (uint32_t*)malloc(n * sizeof(uint32_t));
89:
90: for (i = 0; i < n; i++)
91: {
92: if (!this->xof->get_bytes(this->xof, sizeof(x), x))
93: {
94: DBG1(DBG_LIB, "could not get bytes from SHAKE128 XOF");
95: free(np);
96: return NULL;
97: }
98:
99: /* Treat x as a 32 bit unsigned little endian integer */
100: t = uletoh32(x);
101:
102: /* Compute Psi_16 distribution */
103: d = 0;
104: for (j = 0; j < 8; j++)
105: {
106: d += (t >> j) & 0x01010101;
107: }
108: a = ((d >> 8) & 0xff) + (d & 0xff);
109: b = ((d >> 16) & 0xff) + (d >> 24);
110: np[i] = (a >= b) ? a - b : a + q - b;
111: }
112:
113: return np;
114: }
115:
116: METHOD(newhope_noise_t, destroy, void,
117: private_newhope_noise_t *this)
118: {
119: this->xof->destroy(this->xof);
120: chunk_free(&this->seed);
121: free(this);
122: }
123:
124: /*
125: * Described in header.
126: */
127: newhope_noise_t *newhope_noise_create(chunk_t seed)
128: {
129: private_newhope_noise_t *this;
130: xof_t *xof;
131:
132: if (seed.len != seed_len)
133: {
134: DBG1(DBG_LIB, "seed for ChaCha20 stream must be 256 bits");
135: return NULL;
136: }
137:
138: xof = lib->crypto->create_xof(lib->crypto, XOF_CHACHA20);
139: if (!xof)
140: {
141: DBG1(DBG_LIB, "could not instantiate ChaCha20 stream");
142: return NULL;
143: }
144:
145: INIT(this,
146: .public = {
147: .get_uniform_bytes = _get_uniform_bytes,
148: .get_binomial_words = _get_binomial_words,
149: .destroy = _destroy,
150: },
151: .xof = xof,
152: .seed = chunk_alloc(seed_len + nonce_len),
153: );
154:
155: /* initialize seed for ChaCha 20 stream */
156: memcpy(this->seed.ptr, seed.ptr, seed_len);
157: memset(this->seed.ptr + seed_len, 0x00, nonce_len);
158:
159: return &this->public;
160: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>