Return to newhope_noise.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / strongswan / src / libstrongswan / plugins / newhope |
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: }