Annotation of embedaddon/strongswan/src/libstrongswan/plugins/newhope/newhope_reconciliation.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: 
                     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>