Annotation of embedaddon/strongswan/src/libstrongswan/plugins/newhope/newhope_noise.c, revision 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>