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>