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>