Annotation of embedaddon/strongswan/src/libstrongswan/plugins/newhope/newhope_ke.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_ke.h"
        !            20: #include "newhope_noise.h"
        !            21: #include "newhope_reconciliation.h"
        !            22: 
        !            23: #include <ntt_fft.h>
        !            24: #include <ntt_fft_reduce.h>
        !            25: #include <crypto/diffie_hellman.h>
        !            26: #include <utils/debug.h>
        !            27: 
        !            28: static const int seed_len =   32;  /* 256 bits */
        !            29: static const int poly_len = 1792;  /* size of 1024 packed 14-bit coefficients */
        !            30: static const int rec_len =   256;  /* size of 1024 packed  2-bit coefficients */
        !            31: 
        !            32: typedef struct private_newhope_ke_t private_newhope_ke_t;
        !            33: 
        !            34: /**
        !            35:  * Private data of an newhope_ke_t object.
        !            36:  */
        !            37: struct private_newhope_ke_t {
        !            38: 
        !            39:        /**
        !            40:         * Public newhope_ke_t interface.
        !            41:         */
        !            42:        newhope_ke_t public;
        !            43: 
        !            44:        /**
        !            45:         * FFT parameter set
        !            46:         */
        !            47:        const ntt_fft_params_t *params;
        !            48: 
        !            49:        /**
        !            50:         * Secret noise polynomial s
        !            51:         */
        !            52:        uint32_t *s;
        !            53: 
        !            54:        /**
        !            55:         * Output polynomial u = a * NTT(s') + NTT(e')
        !            56:         */
        !            57:        uint32_t *u;
        !            58: 
        !            59:        /**
        !            60:         * Error reconciliation help bits
        !            61:         */
        !            62:        uint8_t *r;
        !            63: 
        !            64:        /**
        !            65:         * Shared secret
        !            66:         */
        !            67:        chunk_t shared_secret;
        !            68: 
        !            69: };
        !            70: 
        !            71: /**
        !            72:  * Derive 14-bit coefficients of polynomial a from 256 bit random seed
        !            73:  * using the SHAKE128 extended output function
        !            74:  */
        !            75: static uint32_t* derive_a_poly(private_newhope_ke_t *this, chunk_t seed)
        !            76: {
        !            77:        uint32_t *a;
        !            78:        uint8_t x[2];
        !            79:        int i = 0;
        !            80:        xof_t *xof;
        !            81: 
        !            82:        xof = lib->crypto->create_xof(lib->crypto, XOF_SHAKE_128);
        !            83:        if (!xof)
        !            84:        {
        !            85:                DBG1(DBG_LIB, "could not instantiate SHAKE128 XOF");
        !            86:                return NULL;
        !            87:        }
        !            88: 
        !            89:        if (!xof->set_seed(xof, seed))
        !            90:        {
        !            91:                DBG1(DBG_LIB, "could not set seed of SHAKE128 XOF");
        !            92:                xof->destroy(xof);
        !            93:                return NULL;
        !            94:        }
        !            95: 
        !            96:        /* allocate dynamic memory for polynomial a */
        !            97:        a = (uint32_t*)malloc(this->params->n * sizeof(uint32_t));
        !            98: 
        !            99:        while (i < this->params->n)
        !           100:        {
        !           101:                if (!xof->get_bytes(xof, sizeof(x), x))
        !           102:                {
        !           103:                        DBG1(DBG_LIB, "could not get bytes from SHAKE128 XOF");
        !           104:                        xof->destroy(xof);
        !           105:                        free(a);
        !           106:                        return NULL;
        !           107:                }
        !           108: 
        !           109:                /*
        !           110:                 * Treat x as a 16 bit unsigned little endian integer
        !           111:                 * and truncate to 14 bits
        !           112:                 */
        !           113:                a[i] = uletoh16(x) & 0x3fff;
        !           114: 
        !           115:                if (a[i] < this->params->q)
        !           116:                {
        !           117:                        i++;
        !           118:                }
        !           119:        }
        !           120:        xof->destroy(xof);
        !           121: 
        !           122:        return a;
        !           123: }
        !           124: 
        !           125: /**
        !           126:  * Pack four 14-bit coefficients into seven consecutive bytes
        !           127:  *
        !           128:  *                       1                   2                   3
        !           129:  *   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
        !           130:  *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        !           131:  *  |L 0 0 0 0 0 0 0|L 1 H 0 0 0 0 0|M 1 1 1 1 1 1 1|L 2 2 2 H 1 1 1|
        !           132:  *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        !           133:  *  |M 2 2 2 2 2 2 2|L 3 3 3 3 3 H 2|H 3 3 3 3 3 3 3|L 0 0 0 0 0 0 0|
        !           134:  *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        !           135:  */
        !           136: static void pack_poly(private_newhope_ke_t *this, uint8_t *x, uint32_t *p)
        !           137: {
        !           138:        int i;
        !           139: 
        !           140:        for (i = 0; i < this->params->n; i += 4)
        !           141:        {
        !           142:                *x++ = (p[i] & 0xff );
        !           143:                *x++ = (p[i]   >>  8) | (p[i+1] << 6);
        !           144:                *x++ = (p[i+1] >>  2);
        !           145:                *x++ = (p[i+1] >> 10) | (p[i+2] << 4);
        !           146:                *x++ = (p[i+2] >>  4);
        !           147:                *x++ = (p[i+2] >> 12) | (p[i+3] << 2);
        !           148:                *x++ = (p[i+3] >>  6);
        !           149:        }
        !           150: }
        !           151: 
        !           152: /**
        !           153:  * Unpack seven consecutive bytes into four 14-bit coefficients
        !           154:  */
        !           155: static uint32_t* unpack_poly(private_newhope_ke_t * this, uint8_t *x)
        !           156: {
        !           157:        uint32_t *p;
        !           158:        int i;
        !           159: 
        !           160:        p = (uint32_t*)malloc(this->params->n * sizeof(uint32_t));
        !           161: 
        !           162:        for (i = 0; i < this->params->n; i += 4)
        !           163:        {
        !           164:                p[i]   =  x[0]       | (((uint32_t)x[1] & 0x3f) <<  8);
        !           165:                p[i+1] = (x[1] >> 6) | (((uint32_t)x[2]) <<  2)
        !           166:                                                         | (((uint32_t)x[3] & 0x0f) << 10);
        !           167:                p[i+2] = (x[3] >> 4) | (((uint32_t)x[4]) <<  4)
        !           168:                                                         | (((uint32_t)x[5] & 0x03) << 12);
        !           169:                p[i+3] = (x[5] >> 2) | (((uint32_t)x[6]) <<  6);
        !           170:                x += 7;
        !           171:        }
        !           172:        for (i = 0; i < this->params->n; i++)
        !           173:        {
        !           174:                if (p[i] >= this->params->q)
        !           175:                {
        !           176:                        DBG1(DBG_LIB, "polynomial coefficient must be smaller than %u",
        !           177:                                                   this->params->q);
        !           178:                        free(p);
        !           179:                        return NULL;
        !           180:                }
        !           181:        }
        !           182:        return p;
        !           183: }
        !           184: 
        !           185: /**
        !           186:  * Multiply and add polynomials in the frequency domain
        !           187:  */
        !           188: static uint32_t* multiply_add_poly(private_newhope_ke_t *this,
        !           189:                                                                   uint32_t *a, uint32_t *e)
        !           190: {
        !           191:        ntt_fft_t *fft;
        !           192:        uint32_t *b, t;
        !           193:        int i;
        !           194: 
        !           195:        /* transform s and h to frequency domain */
        !           196:        fft = ntt_fft_create(this->params);
        !           197:        fft->transform(fft, this->s, this->s, FALSE);
        !           198:        fft->transform(fft, e, e, FALSE);
        !           199:        fft->destroy(fft);
        !           200: 
        !           201:        b = (uint32_t*)malloc(this->params->n * sizeof(uint32_t));
        !           202: 
        !           203:        /* compute  b = a * s + e in the frequency domain */
        !           204:        for (i = 0; i < this->params->n; i++)
        !           205:        {
        !           206:                /* convert a[i] to Montgomery domain */
        !           207:                t = ntt_fft_mreduce(a[i] * this->params->r2, this->params);
        !           208: 
        !           209:                /* compute b[i] = a[i] * s[i] + e[i] in Montgomery domain */
        !           210:                t = ntt_fft_mreduce(t * this->s[i], this->params) + e[i];
        !           211: 
        !           212:                /* exit Montgomery domain before transmitting polynomial b */
        !           213:                b[i] = ntt_fft_mreduce(t, this->params);
        !           214:        }
        !           215:        memwipe(e, this->params->n * sizeof(uint32_t));
        !           216: 
        !           217:        return b;
        !           218: }
        !           219: 
        !           220: /**
        !           221:  * Multiply polynomials in the frequency domain and return to time domain
        !           222:  */
        !           223: static uint32_t* multiply_ntt_inv_poly(private_newhope_ke_t *this, uint32_t *b)
        !           224: {
        !           225:        ntt_fft_t *fft;
        !           226:        uint32_t *v, t;
        !           227:        int i;
        !           228: 
        !           229:        v = (uint32_t*)malloc(this->params->n * sizeof(uint32_t));
        !           230: 
        !           231:        for (i = 0; i < this->params->n; i++)
        !           232:        {
        !           233:                /* convert b[i] to Montgomery domain */
        !           234:                t = ntt_fft_mreduce(b[i] * this->params->r2, this->params);
        !           235: 
        !           236:                /* compute v[i] = b[i] * s[i] in Montgomery domain */
        !           237:                v[i] = ntt_fft_mreduce(t * this->s[i], this->params);
        !           238:        }
        !           239: 
        !           240:        /* transform v back to time domain */
        !           241:        fft = ntt_fft_create(this->params);
        !           242:        fft->transform(fft, v, v, TRUE);
        !           243:        fft->destroy(fft);
        !           244: 
        !           245:        return v;
        !           246: }
        !           247: 
        !           248: /**
        !           249:  * Pack four 2-bit coefficients into one byte
        !           250:  */
        !           251: static void pack_rec(private_newhope_ke_t *this, uint8_t *x, uint8_t *r)
        !           252: {
        !           253:        int i;
        !           254: 
        !           255:        for (i = 0; i < this->params->n; i += 4)
        !           256:        {
        !           257:                *x++ = r[i] | r[i+1] << 2 | r[i+2] << 4 | r[i+3] << 6;
        !           258:        }
        !           259: }
        !           260: 
        !           261: static uint8_t* unpack_rec(private_newhope_ke_t *this, uint8_t *x)
        !           262: {
        !           263:        uint8_t *r;
        !           264:        int i;
        !           265: 
        !           266:        r = (uint8_t*)malloc(this->params->n);
        !           267: 
        !           268:        for (i = 0; i < this->params->n; i += 4)
        !           269:        {
        !           270:                r[i]   = (*x)      & 0x03;
        !           271:                r[i+1] = (*x >> 2) & 0x03;
        !           272:                r[i+2] = (*x >> 4) & 0x03;
        !           273:                r[i+3] = (*x >> 6) & 0x03;
        !           274:                x++;
        !           275:        }
        !           276: 
        !           277:        return r;
        !           278: }
        !           279: 
        !           280: METHOD(diffie_hellman_t, get_my_public_value, bool,
        !           281:        private_newhope_ke_t *this, chunk_t *value)
        !           282: {
        !           283:        uint16_t n, q;
        !           284:        int i;
        !           285: 
        !           286:        /* Define some often-used constants */
        !           287:        n = this->params->n;
        !           288:        q = this->params->q;
        !           289: 
        !           290:        /* are we the initiator? */
        !           291:        if (this->u == NULL)
        !           292:        {
        !           293:                rng_t *rng;
        !           294:                uint32_t *a = NULL, *b = NULL, *e = NULL;
        !           295:                uint8_t noise_seed_buf[seed_len];
        !           296:                chunk_t noise_seed = { noise_seed_buf, seed_len};
        !           297:                chunk_t a_seed;
        !           298:                newhope_noise_t *noise = NULL;
        !           299:                bool success = FALSE;
        !           300: 
        !           301:                /* allocate space for public output value */
        !           302:                *value = chunk_alloc(poly_len + seed_len);
        !           303:                a_seed = chunk_create(value->ptr + poly_len, seed_len);
        !           304: 
        !           305:                /* create polynomial a from 256 bit random seed */
        !           306:                rng = lib->crypto->create_rng(lib->crypto, RNG_STRONG);
        !           307:                if (!rng)
        !           308:                {
        !           309:                        DBG1(DBG_LIB, "could not instantiate random source");
        !           310:                        return FALSE;
        !           311:                }
        !           312:                if (!rng->get_bytes(rng, seed_len, a_seed.ptr))
        !           313:                {
        !           314:                        DBG1(DBG_LIB, "could not generate seed for polynomial a");
        !           315:                        goto end;
        !           316:                }
        !           317: 
        !           318:                a = derive_a_poly(this, a_seed);
        !           319:                if (a == NULL)
        !           320:                {
        !           321:                        goto end;
        !           322:                }
        !           323: 
        !           324:                /* generate random seed for the derivation of noise polynomials */
        !           325:                if (!rng->get_bytes(rng, seed_len, noise_seed.ptr))
        !           326:                {
        !           327:                        DBG1(DBG_LIB, "could not generate seed for noise polynomials");
        !           328:                        goto end;
        !           329:                }
        !           330: 
        !           331:                /* create noise polynomial generator */
        !           332:                noise = newhope_noise_create(noise_seed);
        !           333:                if (!noise)
        !           334:                {
        !           335:                        goto end;
        !           336:                }
        !           337: 
        !           338:                /* create noise polynomial s from seed with nonce = 0x00 */
        !           339:                this->s = noise->get_binomial_words(noise, 0x00, n, q);
        !           340:                if (this->s == NULL)
        !           341:                {
        !           342:                        goto end;
        !           343:                }
        !           344: 
        !           345:                /* create noise polynomial e from seed with nonce = 0x01 */
        !           346:                e = noise->get_binomial_words(noise, 0x01, n, q);
        !           347:                if (e == NULL)
        !           348:                {
        !           349:                        goto end;
        !           350:                }
        !           351: 
        !           352:                /* compute b = a * NTT(s) + NTT(e) */
        !           353:                b = multiply_add_poly(this, a, e);
        !           354: 
        !           355:                DBG3(DBG_LIB, "   i  a[i]  b[i]");
        !           356:                for (i = 0; i < n; i++)
        !           357:                {
        !           358:                        DBG3(DBG_LIB, "%4d %5u %5u", i, a[i], b[i]);
        !           359:                }
        !           360: 
        !           361:                /* pack coefficients of polynomial b */
        !           362:                pack_poly(this, value->ptr, b);
        !           363:                success = TRUE;
        !           364: 
        !           365:        end:
        !           366:                rng->destroy(rng);
        !           367:                DESTROY_IF(noise);
        !           368:                free(a);
        !           369:                free(b);
        !           370:                free(e);
        !           371: 
        !           372:                if (!success)
        !           373:                {
        !           374:                chunk_free(value);
        !           375:                }
        !           376:                return success;
        !           377:        }
        !           378:        else
        !           379:        {
        !           380:                DBG3(DBG_LIB, "   i  u[i]  r[i]");
        !           381:                for (i = 0; i < n; i++)
        !           382:                {
        !           383:                        DBG3(DBG_LIB, "%4d %5u %5u", i, this->u[i], this->r[i]);
        !           384:                }
        !           385: 
        !           386:                /* allocate space for public output value */
        !           387:                *value = chunk_alloc(poly_len + rec_len);
        !           388: 
        !           389:                /* pack coefficients of polynomial u */
        !           390:                pack_poly(this, value->ptr, this->u);
        !           391: 
        !           392:                /* pack coefficients of polynomial r */
        !           393:                pack_rec(this, value->ptr + poly_len, this->r);
        !           394: 
        !           395:                return TRUE;
        !           396:        }
        !           397: }
        !           398: 
        !           399: METHOD(diffie_hellman_t, get_shared_secret, bool,
        !           400:        private_newhope_ke_t *this, chunk_t *secret)
        !           401: {
        !           402:        if (this->shared_secret.len == 0)
        !           403:        {
        !           404:                *secret = chunk_empty;
        !           405:                return FALSE;
        !           406:        }
        !           407:        *secret = chunk_clone(this->shared_secret);
        !           408: 
        !           409:        return TRUE;
        !           410: }
        !           411: 
        !           412: METHOD(diffie_hellman_t, set_other_public_value, bool,
        !           413:        private_newhope_ke_t *this, chunk_t value)
        !           414: {
        !           415:        newhope_reconciliation_t * rec;
        !           416:        uint16_t n, q;
        !           417:        int i;
        !           418: 
        !           419:        /* Define some often-used constants */
        !           420:        n = this->params->n;
        !           421:        q = this->params->q;
        !           422: 
        !           423:        /* are we the responder? */
        !           424:        if (this->s == NULL)
        !           425:        {
        !           426:                uint32_t *a = NULL, *b = NULL, *e1 = NULL, *e2 = NULL, *v = NULL, t;
        !           427:                uint8_t *rbits = NULL;
        !           428:                uint8_t noise_seed_buf[seed_len];
        !           429:                chunk_t noise_seed = { noise_seed_buf, seed_len };
        !           430:                chunk_t a_seed;
        !           431:                newhope_noise_t *noise = NULL;
        !           432:                rng_t *rng = NULL;
        !           433:                bool success = FALSE;
        !           434: 
        !           435:                if (value.len != poly_len + seed_len)
        !           436:                {
        !           437:                        DBG1(DBG_LIB, "received %N KE payload of incorrect size",
        !           438:                                                   diffie_hellman_group_names, NH_128_BIT);
        !           439:                        return FALSE;
        !           440:                }
        !           441:                a_seed = chunk_create(value.ptr + poly_len, seed_len);
        !           442: 
        !           443:                a = derive_a_poly(this, a_seed);
        !           444:                if (a == NULL)
        !           445:                {
        !           446:                        return FALSE;
        !           447:                }
        !           448: 
        !           449:                b = unpack_poly(this, value.ptr);
        !           450:                if (b == NULL)
        !           451:                {
        !           452:                        goto end;
        !           453:                }
        !           454: 
        !           455:                /* debug output of polynomials a and b */
        !           456:                DBG3(DBG_LIB, "   i  a[i]  b[i]");
        !           457:                for (i = 0; i < n; i++)
        !           458:                {
        !           459:                        DBG3(DBG_LIB, "%4d %5u %5u", i, a[i], b[i]);
        !           460:                }
        !           461: 
        !           462:                /* generate random seed for the derivation of noise polynomials */
        !           463:                rng = lib->crypto->create_rng(lib->crypto, RNG_STRONG);
        !           464:                if (!rng)
        !           465:                {
        !           466:                        DBG1(DBG_LIB, "could not instantiate random source");
        !           467:                        goto end;
        !           468:                }
        !           469:                if (!rng->get_bytes(rng, seed_len, noise_seed.ptr))
        !           470:                {
        !           471:                        DBG1(DBG_LIB, "could not generate seed for noise polynomials");
        !           472:                        goto end;
        !           473:                }
        !           474: 
        !           475:                /* create noise polynomial generator */
        !           476:                noise = newhope_noise_create(noise_seed);
        !           477:                if (!noise)
        !           478:                {
        !           479:                        goto end;
        !           480:                }
        !           481: 
        !           482:                /* create noise polynomial s' from seed with nonce = 0x00 */
        !           483:                this->s = noise->get_binomial_words(noise, 0x00, n, q);
        !           484:                if (this->s == NULL)
        !           485:                {
        !           486:                        goto end;
        !           487:                }
        !           488: 
        !           489:                /* create noise polynomial e' from seed with nonce = 0x01 */
        !           490:                e1 = noise->get_binomial_words(noise, 0x01, n, q);
        !           491:                if (e1 == NULL)
        !           492:                {
        !           493:                        goto end;
        !           494:                }
        !           495: 
        !           496:                /* create noise polynomial e'' from seed with nonce = 0x02 */
        !           497:                e2 = noise->get_binomial_words(noise, 0x02, n, q);
        !           498:                if (e2 == NULL)
        !           499:                {
        !           500:                        goto end;
        !           501:                }
        !           502: 
        !           503:                /* compute u = a * NTT(s') + NTT(e') */
        !           504:                this->u = multiply_add_poly(this, a, e1);
        !           505: 
        !           506:                /* compute v = NTT_inv( b * NTT(s') ) */
        !           507:                v = multiply_ntt_inv_poly(this, b);
        !           508: 
        !           509:                /* compute v = v + e'' */
        !           510:                for (i = 0; i < n; i++)
        !           511:                {
        !           512:                        t = v[i] + e2[i];
        !           513:                        v[i] = (t < q) ? t : t - q;
        !           514:                }
        !           515:                memwipe(e2, n * sizeof(uint32_t));
        !           516: 
        !           517:                /* create uniform noise bytes from seed with nonce = 0x02 */
        !           518:                rbits = noise->get_uniform_bytes(noise, 0x03, n/(4*8));
        !           519: 
        !           520:                rec = newhope_reconciliation_create(n, q);
        !           521:                this->r = rec->help_reconcile(rec, v, rbits);
        !           522:                free(rbits);
        !           523:                this->shared_secret = rec->reconcile(rec, v, this->r);
        !           524:                rec->destroy(rec);
        !           525: 
        !           526:                DBG4(DBG_LIB, "key: %B", &this->shared_secret);
        !           527:                success = TRUE;
        !           528: 
        !           529:        end:
        !           530:                DESTROY_IF(rng);
        !           531:                DESTROY_IF(noise);
        !           532:                free(a);
        !           533:                free(b);
        !           534:                free(e1);
        !           535:                free(e2);
        !           536:                free(v);
        !           537: 
        !           538:                return success;
        !           539:        }
        !           540:        else
        !           541:        {
        !           542:                uint32_t *v;
        !           543: 
        !           544:                if (value.len != poly_len + rec_len)
        !           545:                {
        !           546:                        DBG1(DBG_LIB, "received %N KE payload of incorrect size",
        !           547:                                                   diffie_hellman_group_names, NH_128_BIT);
        !           548:                        return FALSE;
        !           549:                }
        !           550: 
        !           551:                this->u = unpack_poly(this, value.ptr);
        !           552:                if (this->u == NULL)
        !           553:                {
        !           554:                        return FALSE;
        !           555:                }
        !           556: 
        !           557:                this->r = unpack_rec(this, value.ptr + poly_len);
        !           558:                if (this->r == NULL)
        !           559:                {
        !           560:                        return FALSE;
        !           561:                }
        !           562: 
        !           563:                DBG3(DBG_LIB, "   i  u[i]  r[i]");
        !           564:                for (i = 0; i < n; i++)
        !           565:                {
        !           566:                        DBG3(DBG_LIB, "%4d %5u %5u", i, this->u[i], this->r[i]);
        !           567:                }
        !           568: 
        !           569:                /* compute v' = NTT_inv( u * NTT(s) ) */
        !           570:                v = multiply_ntt_inv_poly(this, this->u);
        !           571: 
        !           572:                rec = newhope_reconciliation_create(n, q);
        !           573:                this->shared_secret = rec->reconcile(rec, v, this->r);
        !           574:                free(v);
        !           575:                rec->destroy(rec);
        !           576: 
        !           577:                DBG4(DBG_LIB, "key: %B", &this->shared_secret);
        !           578: 
        !           579:                return TRUE;
        !           580:        }
        !           581: }
        !           582: 
        !           583: METHOD(diffie_hellman_t, get_dh_group, diffie_hellman_group_t,
        !           584:        private_newhope_ke_t *this)
        !           585: {
        !           586:        return NH_128_BIT;
        !           587: }
        !           588: 
        !           589: METHOD(diffie_hellman_t, destroy, void,
        !           590:        private_newhope_ke_t *this)
        !           591: {
        !           592:        chunk_clear(&this->shared_secret);
        !           593:        memwipe(this->s, this->params->n * sizeof(uint32_t));
        !           594:        free(this->s);
        !           595:        free(this->u);
        !           596:        free(this->r);
        !           597:        free(this);
        !           598: }
        !           599: 
        !           600: /*
        !           601:  * Described in header.
        !           602:  */
        !           603: newhope_ke_t *newhope_ke_create(diffie_hellman_group_t group, chunk_t g, chunk_t p)
        !           604: {
        !           605:        private_newhope_ke_t *this;
        !           606: 
        !           607:        INIT(this,
        !           608:                .public = {
        !           609:                        .dh = {
        !           610:                                .get_shared_secret = _get_shared_secret,
        !           611:                                .set_other_public_value = _set_other_public_value,
        !           612:                                .get_my_public_value = _get_my_public_value,
        !           613:                                .get_dh_group = _get_dh_group,
        !           614:                                .destroy = _destroy,
        !           615:                        },
        !           616:                },
        !           617:                .params = &ntt_fft_12289_1024,
        !           618: 
        !           619:        );
        !           620: 
        !           621:        return &this->public;
        !           622: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>