Annotation of embedaddon/strongswan/src/libstrongswan/plugins/newhope/newhope_reconciliation.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:
! 20: #include "newhope_reconciliation.h"
! 21:
! 22: typedef struct private_newhope_reconciliation_t private_newhope_reconciliation_t;
! 23:
! 24: /**
! 25: * Private data of an newhope_reconciliation_t object.
! 26: */
! 27: struct private_newhope_reconciliation_t {
! 28:
! 29: /**
! 30: * Public newhope_reconciliation_t interface.
! 31: */
! 32: newhope_reconciliation_t public;
! 33:
! 34: /**
! 35: * Array sizes
! 36: */
! 37: int n, n4;
! 38:
! 39: /**
! 40: * Multiples of modulus q
! 41: */
! 42: int32_t q, q2, q4, q8, q16;
! 43: };
! 44:
! 45:
! 46: static inline int32_t rec_abs(int32_t v)
! 47: {
! 48: int32_t mask = v >> 31;
! 49:
! 50: return (v ^ mask) - mask;
! 51: }
! 52:
! 53: /**
! 54: * Auxiliary function used by help_reconcile() method
! 55: */
! 56: static int32_t rec_f(private_newhope_reconciliation_t *this,
! 57: int32_t v, uint8_t r, int32_t *v0, int32_t *v1)
! 58: {
! 59: int32_t x, xit, t, b;
! 60:
! 61: x = 8 * v + 2 * r;
! 62:
! 63: /* compute t = x/q */
! 64: b = x * 2730;
! 65: t = b >> 25;
! 66: b = x - t * this->q;
! 67: b = this->q - 1 - b;
! 68: b >>= 31;
! 69: t -= b;
! 70:
! 71: r = t & 0x01;
! 72: xit = (t >> 1);
! 73: *v0 = xit + r ; /* v0 = round(x/(2q)) */
! 74:
! 75: t -= 1;
! 76: r = t & 0x01;
! 77: *v1 = ( t>> 1) + r;
! 78:
! 79: return rec_abs(x - (*v0) * this->q2);
! 80: }
! 81:
! 82: /**
! 83: * Auxiliary function used by reconcile() method
! 84: */
! 85: static int32_t rec_g(private_newhope_reconciliation_t *this, int32_t x)
! 86: {
! 87: int32_t t, r, b;
! 88:
! 89: /* t = x/(4*q) */
! 90: b = x * 2730;
! 91: t = b >> 27;
! 92: b = x - t * this->q4;
! 93: b = this->q4 - 1 - b;
! 94: b >>= 31;
! 95: t -= b;
! 96:
! 97: r = t & 0x01;
! 98: t = (t >> 1) + r; /* t = round(x/(8q)) */
! 99: t *= this->q8;
! 100:
! 101: return abs(t - x);
! 102: }
! 103:
! 104: METHOD(newhope_reconciliation_t, help_reconcile, uint8_t*,
! 105: private_newhope_reconciliation_t *this, uint32_t *v, uint8_t *rbits)
! 106: {
! 107: int32_t v0[4], v1[4], v_tmp[4], k;
! 108: int i, i0, i1, i2, i3, j;
! 109: uint8_t *r, rbit;
! 110:
! 111: /* allocate output vector */
! 112: r = (uint8_t*)malloc(this->n);
! 113:
! 114: for (i = 0; i < this->n4/8; i++)
! 115: {
! 116: for (j = 0; j < 8; j++)
! 117: {
! 118: i0 = 8*i + j;
! 119: i1 = i0 + this->n4;
! 120: i2 = i1 + this->n4;
! 121: i3 = i2 + this->n4;
! 122:
! 123: /* iterate through all 256 random bits */
! 124: rbit = (rbits[i] >> j) & 0x01;
! 125:
! 126: k = rec_f(this, v[i0], rbit, &v0[0], &v1[0]);
! 127: k += rec_f(this, v[i1], rbit, &v0[1], &v1[1]);
! 128: k += rec_f(this, v[i2], rbit, &v0[2], &v1[2]);
! 129: k += rec_f(this, v[i3], rbit, &v0[3], &v1[3]);
! 130:
! 131: k = (this->q2 - 1 - k) >> 31;
! 132:
! 133: v_tmp[0] = ((~k) & v0[0]) ^ (k & v1[0]);
! 134: v_tmp[1] = ((~k) & v0[1]) ^ (k & v1[1]);
! 135: v_tmp[2] = ((~k) & v0[2]) ^ (k & v1[2]);
! 136: v_tmp[3] = ((~k) & v0[3]) ^ (k & v1[3]);
! 137:
! 138: r[i0] = (v_tmp[0] - v_tmp[3]) & 0x03;
! 139: r[i1] = (v_tmp[1] - v_tmp[3]) & 0x03;
! 140: r[i2] = (v_tmp[2] - v_tmp[3]) & 0x03;
! 141: r[i3] = (v_tmp[3] - k + v_tmp[3]) & 0x03;
! 142: }
! 143: }
! 144:
! 145: return r;
! 146: }
! 147:
! 148: METHOD(newhope_reconciliation_t, reconcile, chunk_t,
! 149: private_newhope_reconciliation_t *this, uint32_t *v, uint8_t *r)
! 150: {
! 151: size_t key_len;
! 152: uint8_t *key;
! 153: int32_t tmp[4], t;
! 154: int i, i0, i1, i2, i3, j;
! 155:
! 156: key_len = this->n4 / 8;
! 157: key = (uint8_t*)malloc(key_len);
! 158: memset(key, 0x00, key_len);
! 159:
! 160: for (i = 0; i < key_len; i++)
! 161: {
! 162: for (j = 0; j < 8; j++)
! 163: {
! 164: i0 = 8*i + j;
! 165: i1 = i0 + this->n4;
! 166: i2 = i1 + this->n4;
! 167: i3 = i2 + this->n4;
! 168:
! 169: tmp[0] = this->q16 + 8 * (int32_t)v[i0] -
! 170: this->q * (2*r[i0] + r[i3]);
! 171: tmp[1] = this->q16 + 8 * (int32_t)v[i1] -
! 172: this->q * (2*r[i1] + r[i3]);
! 173: tmp[2] = this->q16 + 8 * (int32_t)v[i2] -
! 174: this->q * (2*r[i2] + r[i3]);
! 175: tmp[3] = this->q16 + 8 * (int32_t)v[i3] -
! 176: this->q * ( r[i3]);
! 177:
! 178: t = rec_g(this, tmp[0]) + rec_g(this, tmp[1]) +
! 179: rec_g(this, tmp[2]) + rec_g(this, tmp[3]) - this->q8;
! 180:
! 181: key[i] |= ((t >> 31) & 0x01) << j;
! 182: }
! 183: }
! 184:
! 185: return chunk_create(key, key_len);
! 186: }
! 187:
! 188: METHOD(newhope_reconciliation_t, destroy, void,
! 189: private_newhope_reconciliation_t *this)
! 190: {
! 191: free(this);
! 192: }
! 193:
! 194: /*
! 195: * Described in header.
! 196: */
! 197: newhope_reconciliation_t *newhope_reconciliation_create(int n, int32_t q)
! 198: {
! 199: private_newhope_reconciliation_t *this;
! 200:
! 201: INIT(this,
! 202: .public = {
! 203: .help_reconcile = _help_reconcile,
! 204: .reconcile = _reconcile,
! 205: .destroy = _destroy,
! 206: },
! 207: .n = n,
! 208: .n4 = n / 4,
! 209: .q = q,
! 210: .q2 = 2 * q,
! 211: .q4 = 4 * q,
! 212: .q8 = 8 * q,
! 213: .q16 = 16 * q,
! 214: );
! 215:
! 216: return &this->public;
! 217: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>