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>