Annotation of embedaddon/strongswan/src/libstrongswan/plugins/bliss/bliss_private_key.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * Copyright (C) 2014-2016 Andreas Steffen
                      3:  * HSR Hochschule fuer Technik Rapperswil
                      4:  *
                      5:  * This program is free software; you can redistribute it and/or modify it
                      6:  * under the terms of the GNU General Public License as published by the
                      7:  * Free Software Foundation; either version 2 of the License, or (at your
                      8:  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
                      9:  *
                     10:  * This program is distributed in the hope that it will be useful, but
                     11:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
                     12:  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
                     13:  * for more details.
                     14:  */
                     15: 
                     16: #include "bliss_private_key.h"
                     17: #include "bliss_public_key.h"
                     18: #include "bliss_param_set.h"
                     19: #include "bliss_utils.h"
                     20: #include "bliss_sampler.h"
                     21: #include "bliss_signature.h"
                     22: #include "bliss_bitpacker.h"
                     23: #include "ntt_fft.h"
                     24: #include "ntt_fft_reduce.h"
                     25: 
                     26: #include <crypto/xofs/xof_bitspender.h>
                     27: #include <asn1/asn1.h>
                     28: #include <asn1/asn1_parser.h>
                     29: #include <asn1/oid.h>
                     30: 
                     31: #define _GNU_SOURCE
                     32: #include <stdlib.h>
                     33: 
                     34: typedef struct private_bliss_private_key_t private_bliss_private_key_t;
                     35: 
                     36: #define SECRET_KEY_TRIALS_MAX  50
                     37: 
                     38: /**
                     39:  * Private data of a bliss_private_key_t object.
                     40:  */
                     41: struct private_bliss_private_key_t {
                     42:        /**
                     43:         * Public interface for this signer.
                     44:         */
                     45:        bliss_private_key_t public;
                     46: 
                     47:        /**
                     48:         * BLISS signature parameter set
                     49:         */
                     50:        const bliss_param_set_t *set;
                     51: 
                     52:        /**
                     53:         * BLISS secret key S1 (coefficients of polynomial f)
                     54:         */
                     55:        int8_t *s1;
                     56: 
                     57:        /**
                     58:         * BLISS secret key S2 (coefficients of polynomial 2g + 1)
                     59:         */
                     60:        int8_t *s2;
                     61: 
                     62:        /**
                     63:         * NTT of BLISS public key a (coefficients of polynomial (2g + 1)/f)
                     64:         */
                     65:        uint32_t *A;
                     66: 
                     67:        /**
                     68:         * NTT of BLISS public key in Montgomery representation Ar = rA mod
                     69:         */
                     70:        uint32_t *Ar;
                     71: 
                     72:        /**
                     73:         * reference count
                     74:         */
                     75:        refcount_t ref;
                     76: };
                     77: 
                     78: METHOD(private_key_t, get_type, key_type_t,
                     79:        private_bliss_private_key_t *this)
                     80: {
                     81:        return KEY_BLISS;
                     82: }
                     83: 
                     84: /**
                     85:  * Multiply secret vector s with binary challenge vector c
                     86:  */
                     87: static void multiply_by_c(int8_t *s, int n, uint16_t *c_indices,
                     88:                                                  uint16_t kappa, int32_t *product)
                     89: {
                     90:        int i, j, index;
                     91: 
                     92:        for (i = 0; i < n; i++)
                     93:        {
                     94:                product[i] = 0;
                     95: 
                     96:                for (j = 0; j < kappa; j++)
                     97:                {
                     98:                        index = c_indices[j];
                     99:                        if (i - index < 0)
                    100:                        {
                    101:                                product[i] -= s[i - index + n];
                    102:                        }
                    103:                        else
                    104:                        {
                    105:                                product[i] += s[i - index];
                    106:                        }
                    107:                }
                    108:        }
                    109: }
                    110: 
                    111: /**
                    112:  * BLISS-B GreedySC algorithm
                    113:  */
                    114: static void greedy_sc(int8_t *s1, int8_t *s2, int n, uint16_t *c_indices,
                    115:                                          uint16_t kappa, int32_t *v1, int32_t *v2)
                    116: {
                    117:        int i, j, index;
                    118:        int32_t sign;
                    119: 
                    120:        for (i = 0; i < n; i++)
                    121:        {
                    122:                v1[i] = v2[i] = 0;
                    123:        }
                    124:        for (j = 0; j < kappa; j++)
                    125:        {
                    126:                index = c_indices[j];
                    127:                sign = 0;
                    128: 
                    129:                for (i = 0; i < index; i++)
                    130:                {
                    131:                        sign -= (v1[i] * s1[i - index + n] + v2[i] * s2[i - index + n]);
                    132:                }
                    133:                for (i = index; i < n; i++)
                    134:                {
                    135:                        sign += (v1[i] * s1[i - index] + v2[i] * s2[i - index]);
                    136:                }
                    137:                for (i = 0; i < index; i++)
                    138:                {
                    139:                        if (sign > 0)
                    140:                        {
                    141:                                v1[i] += s1[i - index + n];
                    142:                                v2[i] += s2[i - index + n];
                    143:                        }
                    144:                        else
                    145:                        {
                    146:                                v1[i] -= s1[i - index + n];
                    147:                                v2[i] -= s2[i - index + n];
                    148:                        }
                    149:                }
                    150:                for (i = index; i < n; i++)
                    151:                {
                    152:                        if (sign > 0)
                    153:                        {
                    154:                                v1[i] -= s1[i - index];
                    155:                                v2[i] -= s2[i - index];
                    156:                        }
                    157:                        else
                    158:                        {
                    159:                                v1[i] += s1[i - index];
                    160:                                v2[i] += s2[i - index];
                    161:                        }
                    162:                }
                    163:        }
                    164: }
                    165: 
                    166: /**
                    167:  * Compute a BLISS signature
                    168:  */
                    169: static bool sign_bliss(private_bliss_private_key_t *this, hash_algorithm_t alg,
                    170:                                           chunk_t data, chunk_t *signature)
                    171: {
                    172:        ntt_fft_t *fft;
                    173:        bliss_signature_t *sig;
                    174:        bliss_sampler_t *sampler = NULL;
                    175:        rng_t *rng;
                    176:        hasher_t *hasher;
                    177:        ext_out_function_t mgf1_alg, oracle_alg;
                    178:        size_t mgf1_seed_len;
                    179:        uint8_t mgf1_seed_buf[HASH_SIZE_SHA512], data_hash_buf[HASH_SIZE_SHA512];
                    180:        chunk_t mgf1_seed, data_hash;
                    181:        uint16_t q, q2, p, p2, *c_indices, tests = 0;
                    182:        uint32_t *ay;
                    183:        int32_t *y1, *y2, *z1, *z2, *u, *s1c, *s2c;
                    184:        int32_t y1_min = 0, y1i, y1_max = 0, y2_min = 0, y2i, y2_max = 0;
                    185:        int32_t scalar, norm, ui;
                    186:        int16_t *ud, *uz2d, *z2d, value;
                    187:        int i, n;
                    188:        double mean1 = 0, mean2 = 0, sigma1 = 0, sigma2 = 0;
                    189:        bool accepted, positive, success = FALSE, use_bliss_b;
                    190: 
                    191:        /* Initialize signature */
                    192:        *signature = chunk_empty;
                    193: 
                    194:        /* Create data hash using configurable hash algorithm */
                    195:        hasher = lib->crypto->create_hasher(lib->crypto, alg);
                    196:        if (!hasher)
                    197:        {
                    198:                return FALSE;
                    199:        }
                    200:        data_hash = chunk_create(data_hash_buf, hasher->get_hash_size(hasher));
                    201: 
                    202:        if (!hasher->get_hash(hasher, data, data_hash_buf))
                    203:        {
                    204:                hasher->destroy(hasher);
                    205:                return FALSE;
                    206:        }
                    207:        hasher->destroy(hasher);
                    208: 
                    209:        /* Set MGF1 hash algorithm and seed length based on security strength */
                    210:        if (this->set->strength > 160)
                    211:        {
                    212:                mgf1_alg = XOF_MGF1_SHA256;
                    213:                mgf1_seed_len = HASH_SIZE_SHA256;
                    214:        }
                    215:        else
                    216:        {
                    217:                mgf1_alg = XOF_MGF1_SHA1;
                    218:                mgf1_seed_len = HASH_SIZE_SHA1;
                    219:        }
                    220:        mgf1_seed = chunk_create(mgf1_seed_buf, mgf1_seed_len);
                    221: 
                    222:        rng = lib->crypto->create_rng(lib->crypto, RNG_STRONG);
                    223:        if (!rng)
                    224:        {
                    225:                return FALSE;
                    226:        }
                    227: 
                    228:        /* MGF1 hash algorithm to be used for random oracle */
                    229:        oracle_alg = XOF_MGF1_SHA512;
                    230: 
                    231:        /* Initialize a couple of needed variables */
                    232:        n  = this->set->n;
                    233:        q  = this->set->q;
                    234:        p  = this->set->p;
                    235:        q2 = 2 * q;
                    236:        p2 = p / 2;
                    237:        ay   = malloc(n * sizeof(uint32_t));
                    238:        z2   = malloc(n * sizeof(int32_t));
                    239:        s1c  = malloc(n * sizeof(int32_t));
                    240:        s2c  = malloc(n * sizeof(int32_t));
                    241:        u    = malloc(n * sizeof(int32_t));
                    242:        uz2d = malloc(n * sizeof(int16_t));
                    243: 
                    244:        sig = bliss_signature_create(this->set);
                    245:        sig->get_parameters(sig, &z1, &z2d, &c_indices);
                    246:        y1 = z1;
                    247:        y2 = z2;
                    248:        ud = z2d;
                    249: 
                    250:        fft = ntt_fft_create(this->set->fft_params);
                    251: 
                    252:        /* Use of the enhanced BLISS-B signature algorithm? */
                    253:        switch (this->set->id)
                    254:        {
                    255:                default:
                    256:                case BLISS_I:
                    257:                case BLISS_II:
                    258:                case BLISS_III:
                    259:                case BLISS_IV:
                    260:                        use_bliss_b = FALSE;
                    261:                        break;
                    262:                case BLISS_B_I:
                    263:                case BLISS_B_II:
                    264:                case BLISS_B_III:
                    265:                case BLISS_B_IV:
                    266:                        use_bliss_b = TRUE;
                    267:                        break;
                    268:        }
                    269: 
                    270:        while (true)
                    271:        {
                    272:                tests++;
                    273: 
                    274:                if (!rng->get_bytes(rng, mgf1_seed_len, mgf1_seed_buf))
                    275:                {
                    276:                        goto end;
                    277:                }
                    278:                DESTROY_IF(sampler);
                    279: 
                    280:                sampler = bliss_sampler_create(mgf1_alg, mgf1_seed, this->set);
                    281:                if (!sampler)
                    282:                {
                    283:                        goto end;
                    284:                }
                    285: 
                    286:                /* Gaussian sampling for vectors y1 and y2 */
                    287:                for (i = 0; i < n; i++)
                    288:                {
                    289:                        if (!sampler->gaussian(sampler, &y1i) ||
                    290:                                !sampler->gaussian(sampler, &y2i))
                    291:                        {
                    292:                                goto end;
                    293:                        }
                    294:                        y1[i] = y1i;
                    295:                        y2[i] = y2i;
                    296: 
                    297:                        /* Collect statistical data on rejection sampling */
                    298:                        if (i == 0)
                    299:                        {
                    300:                                y1_min = y1_max = y1i;
                    301:                                y2_min = y2_max = y2i;
                    302:                        }
                    303:                        else
                    304:                        {
                    305:                                if (y1i < y1_min)
                    306:                                {
                    307:                                        y1_min = y1i;
                    308:                                }
                    309:                                else if (y1i > y1_max)
                    310:                                {
                    311:                                        y1_max = y1i;
                    312:                                }
                    313:                                if (y2i < y2_min)
                    314:                                {
                    315:                                        y2_min = y2i;
                    316:                                }
                    317:                                else if (y2i > y2_max)
                    318:                                {
                    319:                                        y2_max = y2i;
                    320:                                }
                    321:                        }
                    322:                        mean1 += y1i;
                    323:                        mean2 += y2i;
                    324:                        sigma1 += y1i * y1i;
                    325:                        sigma2 += y2i * y2i;
                    326: 
                    327:                        ay[i] = y1i < 0 ? q + y1i : y1i;
                    328:                }
                    329: 
                    330:                /* Compute statistics on vectors y1 and y2 */
                    331:                mean1 /= n;
                    332:                mean2 /= n;
                    333:                sigma1 /= n;
                    334:                sigma2 /= n;
                    335:                sigma2 -= mean1 * mean1;
                    336:                sigma2 -= mean2 * mean2;
                    337:                DBG2(DBG_LIB, "y1 = %d..%d (sigma2 = %5.0f, mean = %4.1f)",
                    338:                                           y1_min, y1_max, sigma1, mean1);
                    339:                DBG2(DBG_LIB, "y2 = %d..%d (sigma2 = %5.0f, mean = %4.1f)",
                    340:                                           y2_min, y2_max, sigma2, mean2);
                    341: 
                    342:                fft->transform(fft, ay, ay, FALSE);
                    343: 
                    344:                for (i = 0; i < n; i++)
                    345:                {
                    346:                        ay[i] = ntt_fft_mreduce(this->Ar[i] * ay[i], this->set->fft_params);
                    347:                }
                    348:                fft->transform(fft, ay, ay, TRUE);
                    349: 
                    350:                for (i = 0; i < n; i++)
                    351:                {
                    352:                        ui = 2 * this->set->q2_inv * (int32_t)ay[i] + y2[i];
                    353:                        u[i] = ((ui < 0) ? q2 + ui : ui) % q2;
                    354:                }
                    355:                bliss_utils_round_and_drop(this->set, u, ud);
                    356: 
                    357:                /* Detailed debugging information */
                    358:                DBG3(DBG_LIB, "  i    u[i]  ud[i]");
                    359:                for (i = 0; i < n; i++)
                    360:                {
                    361:                        DBG3(DBG_LIB, "%3d  %6d   %4d", i, u[i], ud[i]);
                    362:                }
                    363: 
                    364:                if (!bliss_utils_generate_c(oracle_alg, data_hash, ud, this->set,
                    365:                                                                        c_indices))
                    366:                {
                    367:                        goto end;
                    368:                }
                    369: 
                    370:                if (use_bliss_b)
                    371:                {
                    372:                        /* Compute v = (s1c, s2c) with the GreedySC algorithm */
                    373:                        greedy_sc(this->s1, this->s2, n, c_indices, this->set->kappa,
                    374:                                          s1c, s2c);
                    375: 
                    376:                        /* Compute norm = ||v||^2 = ||Sc'||^2 */
                    377:                        norm = bliss_utils_scalar_product(s1c, s1c, n) +
                    378:                                   bliss_utils_scalar_product(s2c, s2c, n);
                    379: 
                    380:                        /* Just in case. ||v||^2 <= P_max should always be fulfilled */
                    381:                        if (norm > this->set->p_max)
                    382:                        {
                    383:                                goto end;
                    384:                        }
                    385:                }
                    386:                else
                    387:                {
                    388:                        /* Compute s*c */
                    389:                        multiply_by_c(this->s1, n, c_indices, this->set->kappa, s1c);
                    390:                        multiply_by_c(this->s2, n, c_indices, this->set->kappa, s2c);
                    391: 
                    392:                        /* Compute norm = |Sc||^2 */
                    393:                        norm = bliss_utils_scalar_product(s1c, s1c, n) +
                    394:                                   bliss_utils_scalar_product(s2c, s2c, n);
                    395:                }
                    396: 
                    397:                if (!sampler->bernoulli_exp(sampler, this->set->M - norm, &accepted))
                    398:                {
                    399:                        goto end;
                    400:                }
                    401:                if (use_bliss_b)
                    402:                {
                    403:                        DBG2(DBG_LIB, "norm2(s1*c') + norm2(s2*c') = %u (%u max), %s",
                    404:                                 norm, this->set->p_max, accepted ? "accepted" : "rejected");
                    405: 
                    406:                }
                    407:                else
                    408:                {
                    409:                        DBG2(DBG_LIB, "norm2(s1*c) + norm2(s2*c) = %u, %s",
                    410:                                 norm, accepted ? "accepted" : "rejected");
                    411:                }
                    412:                if (!accepted)
                    413:                {
                    414:                        continue;
                    415:                }
                    416: 
                    417:                /* Compute z */
                    418:                if (!sampler->sign(sampler, &positive))
                    419:                {
                    420:                        goto end;
                    421:                }
                    422:                for (i = 0; i < n; i++)
                    423:                {
                    424:                        if (positive)
                    425:                        {
                    426:                                z1[i] = y1[i] + s1c[i];
                    427:                                z2[i] = y2[i] + s2c[i];
                    428:                        }
                    429:                        else
                    430:                        {
                    431:                                z1[i] = y1[i] - s1c[i];
                    432:                                z2[i] = y2[i] - s2c[i];
                    433:                        }
                    434:                }
                    435:                /* Reject with probability 1/cosh(scalar/sigma^2) */
                    436:                scalar = bliss_utils_scalar_product(z1, s1c, n) +
                    437:                                 bliss_utils_scalar_product(z2, s2c, n);
                    438: 
                    439:                if (!sampler->bernoulli_cosh(sampler, scalar, &accepted))
                    440:                {
                    441:                        goto end;
                    442:                }
                    443:                DBG2(DBG_LIB, "scalar(z1,s1*c) + scalar(z2,s2*c) = %d, %s",
                    444:                                           scalar, accepted ? "accepted" : "rejected");
                    445:                if (!accepted)
                    446:                {
                    447:                        continue;
                    448:                }
                    449: 
                    450:                /* Compute z2 with dropped bits */
                    451:                for (i = 0; i < n; i++)
                    452:                {
                    453:                        u[i] -= z2[i];
                    454:                        if (u[i] < 0)
                    455:                        {
                    456:                                u[i] += q2;
                    457:                        }
                    458:                        else if (u[i] >= q2)
                    459:                        {
                    460:                                u[i] -= q2;
                    461:                        }
                    462:                }
                    463:                bliss_utils_round_and_drop(this->set, u, uz2d);
                    464: 
                    465:                for (i = 0; i < n; i++)
                    466:                {
                    467:                        value = ud[i] - uz2d[i];
                    468:                        if (value <= -p2)
                    469:                        {
                    470:                                value += p;
                    471:                        }
                    472:                        else if (value > p2)
                    473:                        {
                    474:                                value -= p;
                    475:                        }
                    476:                        z2d[i] = value;
                    477:                }
                    478: 
                    479:                if (!bliss_utils_check_norms(this->set, z1, z2d))
                    480:                {
                    481:                        continue;
                    482:                }
                    483: 
                    484:                *signature = sig->get_encoding(sig);
                    485:                if (signature->len == 0)
                    486:                {
                    487:                        DBG1(DBG_LIB, "inefficient Huffman coding of signature");
                    488:                        continue;
                    489:                }
                    490:                DBG2(DBG_LIB, "signature generation needed %u round%s", tests,
                    491:                                          (tests == 1) ? "" : "s");
                    492:                break;
                    493:        }
                    494:        success = TRUE;
                    495: 
                    496: end:
                    497:        /* cleanup */
                    498:        DESTROY_IF(sampler);
                    499:        sig->destroy(sig);
                    500:        fft->destroy(fft);
                    501:        rng->destroy(rng);
                    502:        memwipe(s1c, n * sizeof(int32_t));
                    503:        memwipe(s2c, n * sizeof(int32_t));
                    504:        free(s1c);
                    505:        free(s2c);
                    506:        free(ay);
                    507:        free(z2);
                    508:        free(u);
                    509:        free(uz2d);
                    510: 
                    511:        return success;
                    512: }
                    513: 
                    514: METHOD(private_key_t, sign, bool,
                    515:        private_bliss_private_key_t *this, signature_scheme_t scheme, void *params,
                    516:        chunk_t data, chunk_t *signature)
                    517: {
                    518:        switch (scheme)
                    519:        {
                    520:                case SIGN_BLISS_WITH_SHA2_256:
                    521:                        return sign_bliss(this, HASH_SHA256, data, signature);
                    522:                case SIGN_BLISS_WITH_SHA2_384:
                    523:                        return sign_bliss(this, HASH_SHA384, data, signature);
                    524:                case SIGN_BLISS_WITH_SHA2_512:
                    525:                        return sign_bliss(this, HASH_SHA512, data, signature);
                    526:                case SIGN_BLISS_WITH_SHA3_256:
                    527:                        return sign_bliss(this, HASH_SHA3_256, data, signature);
                    528:                case SIGN_BLISS_WITH_SHA3_384:
                    529:                        return sign_bliss(this, HASH_SHA3_384, data, signature);
                    530:                case SIGN_BLISS_WITH_SHA3_512:
                    531:                        return sign_bliss(this, HASH_SHA3_512, data, signature);
                    532:                default:
                    533:                        DBG1(DBG_LIB, "signature scheme %N not supported with BLISS",
                    534:                                 signature_scheme_names, scheme);
                    535:                        return FALSE;
                    536:        }
                    537: }
                    538: 
                    539: METHOD(private_key_t, decrypt, bool,
                    540:        private_bliss_private_key_t *this, encryption_scheme_t scheme,
                    541:        chunk_t crypto, chunk_t *plain)
                    542: {
                    543:        DBG1(DBG_LIB, "encryption scheme %N not supported",
                    544:                                   encryption_scheme_names, scheme);
                    545:        return FALSE;
                    546: }
                    547: 
                    548: METHOD(private_key_t, get_keysize, int,
                    549:        private_bliss_private_key_t *this)
                    550: {
                    551:        return this->set->strength;
                    552: }
                    553: 
                    554: METHOD(private_key_t, get_public_key, public_key_t*,
                    555:        private_bliss_private_key_t *this)
                    556: {
                    557:        public_key_t *public;
                    558:        chunk_t pubkey;
                    559: 
                    560:        pubkey = bliss_public_key_info_encode(this->set->oid, this->A, this->set);
                    561:        public = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_BLISS,
                    562:                                                                BUILD_BLOB_ASN1_DER, pubkey, BUILD_END);
                    563:        free(pubkey.ptr);
                    564: 
                    565:        return public;
                    566: }
                    567: 
                    568: METHOD(private_key_t, get_encoding, bool,
                    569:        private_bliss_private_key_t *this, cred_encoding_type_t type,
                    570:        chunk_t *encoding)
                    571: {
                    572:        switch (type)
                    573:        {
                    574:                case PRIVKEY_ASN1_DER:
                    575:                case PRIVKEY_PEM:
                    576:                {
                    577:                        chunk_t s1, s2, pubkey;
                    578:                        bliss_bitpacker_t *packer;
                    579:                        size_t s_bits;
                    580:                        int8_t value;
                    581:                        bool success = TRUE;
                    582:                        int i;
                    583: 
                    584:                        pubkey = bliss_public_key_encode(this->A, this->set);
                    585: 
                    586:                        /* Use either 2 or 3 bits per array element */
                    587:                        s_bits = 2 + (this->set->non_zero2 > 0);
                    588: 
                    589:                        /* Encode secret s1 */
                    590:                        packer = bliss_bitpacker_create(s_bits * this->set->n);
                    591:                        for (i = 0; i < this->set->n; i++)
                    592:                        {
                    593:                                packer->write_bits(packer, this->s1[i], s_bits);
                    594:                        }
                    595:                        s1 = packer->extract_buf(packer);
                    596:                        packer->destroy(packer);
                    597: 
                    598:                        /* Encode secret s2 */
                    599:                        packer = bliss_bitpacker_create(s_bits * this->set->n);
                    600:                        for (i = 0; i < this->set->n; i++)
                    601:                        {
                    602:                                value = this->s2[i];
                    603:                                if (i == 0)
                    604:                                {
                    605:                                        value -= 1;
                    606:                                }
                    607:                                value /= 2;
                    608:                                packer->write_bits(packer, value, s_bits);
                    609:                        }
                    610:                        s2 = packer->extract_buf(packer);
                    611:                        packer->destroy(packer);
                    612: 
                    613:                        *encoding = asn1_wrap(ASN1_SEQUENCE, "mmss",
                    614:                                                        asn1_build_known_oid(this->set->oid),
                    615:                                                        asn1_bitstring("m", pubkey),
                    616:                                                        asn1_bitstring("m", s1),
                    617:                                                        asn1_bitstring("m", s2)
                    618:                                                );
                    619:                        if (type == PRIVKEY_PEM)
                    620:                        {
                    621:                                chunk_t asn1_encoding = *encoding;
                    622: 
                    623:                                success = lib->encoding->encode(lib->encoding, PRIVKEY_PEM,
                    624:                                                                NULL, encoding, CRED_PART_BLISS_PRIV_ASN1_DER,
                    625:                                                                asn1_encoding, CRED_PART_END);
                    626:                                chunk_clear(&asn1_encoding);
                    627:                        }
                    628:                        return success;
                    629:                }
                    630:                default:
                    631:                        return FALSE;
                    632:        }
                    633: }
                    634: 
                    635: METHOD(private_key_t, get_fingerprint, bool,
                    636:        private_bliss_private_key_t *this, cred_encoding_type_t type, chunk_t *fp)
                    637: {
                    638:        bool success;
                    639: 
                    640:        if (lib->encoding->get_cache(lib->encoding, type, this, fp))
                    641:        {
                    642:                return TRUE;
                    643:        }
                    644:        success = bliss_public_key_fingerprint(this->set->oid, this->A,
                    645:                                                                                   this->set, type, fp);
                    646:        if (success)
                    647:        {
                    648:                lib->encoding->cache(lib->encoding, type, this, *fp);
                    649:        }
                    650:        return success;
                    651: }
                    652: 
                    653: METHOD(private_key_t, get_ref, private_key_t*,
                    654:        private_bliss_private_key_t *this)
                    655: {
                    656:        ref_get(&this->ref);
                    657:        return &this->public.key;
                    658: }
                    659: 
                    660: METHOD(private_key_t, destroy, void,
                    661:        private_bliss_private_key_t *this)
                    662: {
                    663:        if (ref_put(&this->ref))
                    664:        {
                    665:                lib->encoding->clear_cache(lib->encoding, this);
                    666:                if (this->s1)
                    667:                {
                    668:                        memwipe(this->s1, this->set->n * sizeof(int8_t));
                    669:                        free(this->s1);
                    670:                }
                    671:                if (this->s2)
                    672:                {
                    673:                        memwipe(this->s2, this->set->n * sizeof(int8_t));
                    674:                        free(this->s2);
                    675:                }
                    676:                free(this->A);
                    677:                free(this->Ar);
                    678:                free(this);
                    679:        }
                    680: }
                    681: 
                    682: /**
                    683:  * Internal generic constructor
                    684:  */
                    685: static private_bliss_private_key_t *bliss_private_key_create_empty(void)
                    686: {
                    687:        private_bliss_private_key_t *this;
                    688: 
                    689:        INIT(this,
                    690:                .public = {
                    691:                        .key = {
                    692:                                .get_type = _get_type,
                    693:                                .sign = _sign,
                    694:                                .decrypt = _decrypt,
                    695:                                .get_keysize = _get_keysize,
                    696:                                .get_public_key = _get_public_key,
                    697:                                .equals = private_key_equals,
                    698:                                .belongs_to = private_key_belongs_to,
                    699:                                .get_fingerprint = _get_fingerprint,
                    700:                                .has_fingerprint = private_key_has_fingerprint,
                    701:                                .get_encoding = _get_encoding,
                    702:                                .get_ref = _get_ref,
                    703:                                .destroy = _destroy,
                    704:                        },
                    705:                },
                    706:                .ref = 1,
                    707:        );
                    708:        return this;
                    709: }
                    710: 
                    711: /**
                    712:  * Compute the scalar product of a vector x with a negative wrapped vector y
                    713:  */
                    714: static int16_t wrapped_product(int8_t *x, int8_t *y, int n, int shift)
                    715: {
                    716:        int16_t product = 0;
                    717:        int i;
                    718: 
                    719:        for (i = 0; i < n - shift; i++)
                    720:        {
                    721:                product += x[i] * y[i + shift];
                    722:        }
                    723:        for (i = n - shift; i < n; i++)
                    724:        {
                    725:                product -= x[i] * y[i + shift - n];
                    726:        }
                    727:        return product;
                    728: }
                    729: 
                    730: /**
                    731:  * Apply a negative wrapped rotation to a vector x
                    732:  */
                    733: static void wrap(int16_t *x, int n, int shift, int16_t *x_wrapped)
                    734: {
                    735:        int i;
                    736: 
                    737:        for (i = 0; i < n - shift; i++)
                    738:        {
                    739:                x_wrapped[i + shift] = x[i];
                    740:        }
                    741:        for (i = n - shift; i < n; i++)
                    742:        {
                    743:                x_wrapped[i + shift - n] = -x[i];
                    744:        }
                    745: }
                    746: 
                    747: /**
                    748:  * int16_t compare function needed for qsort()
                    749:  */
                    750: static int compare(const int16_t *a, const int16_t *b)
                    751: {
                    752:        int16_t temp = *a - *b;
                    753: 
                    754:        if (temp > 0)
                    755:        {
                    756:                return 1;
                    757:        }
                    758:        else if (temp < 0)
                    759:        {
                    760:                return -1;
                    761:        }
                    762:        else
                    763:        {
                    764:                return 0;
                    765:        }
                    766: }
                    767: 
                    768: /**
                    769:  * Compute the Nk(S) norm of S = (s1, s2)
                    770:  */
                    771: static uint32_t nks_norm(int8_t *s1, int8_t *s2, int n, uint16_t kappa)
                    772: {
                    773:        int16_t t[n], t_wrapped[n], max_kappa[n];
                    774:        uint32_t nks = 0;
                    775:        int i, j;
                    776: 
                    777:        for (i = 0; i < n; i++)
                    778:        {
                    779:                t[i] = wrapped_product(s1, s1, n, i) + wrapped_product(s2, s2, n, i);
                    780:        }
                    781: 
                    782:        for (i = 0; i < n; i++)
                    783:        {
                    784:                wrap(t, n, i, t_wrapped);
                    785:                qsort(t_wrapped, n, sizeof(int16_t), (void*)compare);
                    786:                max_kappa[i] = 0;
                    787: 
                    788:                for (j = 1; j <= kappa; j++)
                    789:                {
                    790:                        max_kappa[i] += t_wrapped[n - j];
                    791:                }
                    792:        }
                    793:        qsort(max_kappa, n, sizeof(int16_t), (void*)compare);
                    794: 
                    795:        for (i = 1; i <= kappa; i++)
                    796:        {
                    797:                nks += max_kappa[n - i];
                    798:        }
                    799:        return nks;
                    800: }
                    801: 
                    802: /**
                    803:  * Compute the inverse x1 of x modulo q as x^(-1) = x^(q-2) mod q
                    804:  */
                    805: static uint32_t invert(private_bliss_private_key_t *this, uint32_t x)
                    806: {
                    807:        uint32_t x1, x2;
                    808:        uint16_t q2;
                    809:        int i, i_max;
                    810: 
                    811:        q2 = this->set->q - 2;
                    812:        x1 = (q2 & 1) ? x : 1;
                    813:        x2 = x;
                    814:        i_max = 15;
                    815: 
                    816:        while ((q2 & (1 << i_max)) == 0)
                    817:        {
                    818:                i_max--;
                    819:        }
                    820:        for (i = 1; i <= i_max; i++)
                    821:        {
                    822:                x2 = ntt_fft_mreduce(x2 * x2, this->set->fft_params);
                    823: 
                    824:                if (q2 & (1 << i))
                    825:                {
                    826:                        x1 = ntt_fft_mreduce(x1 * x2, this->set->fft_params);
                    827:                }
                    828:        }
                    829: 
                    830:        return x1;
                    831: }
                    832: 
                    833: /**
                    834:  * Create a vector with sparse and small coefficients from seed
                    835:  */
                    836: static int8_t* create_vector_from_seed(private_bliss_private_key_t *this,
                    837:                                                                           ext_out_function_t alg, chunk_t seed)
                    838: {
                    839:        xof_bitspender_t *bitspender;
                    840:        uint32_t index, sign;
                    841:        int8_t *vector;
                    842:        int non_zero;
                    843: 
                    844:        bitspender = xof_bitspender_create(alg, seed, FALSE);
                    845:        if (!bitspender)
                    846:        {
                    847:            return NULL;
                    848:        }
                    849: 
                    850:        vector = malloc(sizeof(int8_t) * this->set->n);
                    851:        memset(vector, 0x00, this->set->n);
                    852: 
                    853:        non_zero = this->set->non_zero1;
                    854:        while (non_zero)
                    855:        {
                    856:                if (!bitspender->get_bits(bitspender, this->set->n_bits, &index))
                    857:                {
                    858:                        free(vector);
                    859:                        return NULL;
                    860:                }
                    861:                if (vector[index] != 0)
                    862:                {
                    863:                        continue;
                    864:                }
                    865: 
                    866:                if (!bitspender->get_bits(bitspender, 1, &sign))
                    867:                {
                    868:                        free(vector);
                    869:                        return NULL;
                    870:                }
                    871:                vector[index] = sign ? 1 : -1;
                    872:                non_zero--;
                    873:        }
                    874: 
                    875:        non_zero = this->set->non_zero2;
                    876:        while (non_zero)
                    877:        {
                    878:                if (!bitspender->get_bits(bitspender, this->set->n_bits, &index))
                    879:                {
                    880:                        free(vector);
                    881:                        return NULL;
                    882:                }
                    883:                if (vector[index] != 0)
                    884:                {
                    885:                        continue;
                    886:                }
                    887: 
                    888:                if (!bitspender->get_bits(bitspender, 1, &sign))
                    889:                {
                    890:                        free(vector);
                    891:                        return NULL;
                    892:                }
                    893:                vector[index] = sign ? 2 : -2;
                    894:                non_zero--;
                    895:        }
                    896:        bitspender->destroy(bitspender);
                    897: 
                    898:        return vector;
                    899: }
                    900: 
                    901: /**
                    902:  * Generate the secret key S = (s1, s2) fulfilling the Nk(S) norm
                    903:  */
                    904: static bool create_secret(private_bliss_private_key_t *this, rng_t *rng,
                    905:                                                 int8_t **s1, int8_t **s2, int *trials)
                    906: {
                    907:        uint8_t seed_buf[32];
                    908:        uint8_t *f, *g;
                    909:        uint32_t l2_norm, nks;
                    910:        int i, n;
                    911:        chunk_t seed;
                    912:        size_t seed_len;
                    913:        ext_out_function_t alg;
                    914: 
                    915:        n = this->set->n;
                    916:        *s1 = NULL;
                    917:        *s2 = NULL;
                    918: 
                    919:        /* Set MGF1 hash algorithm and seed length based on security strength */
                    920:        if (this->set->strength > 160)
                    921:        {
                    922:                alg = XOF_MGF1_SHA256;
                    923:                seed_len = HASH_SIZE_SHA256;
                    924:        }
                    925:        else
                    926:        {
                    927:                alg = XOF_MGF1_SHA1;
                    928:                seed_len = HASH_SIZE_SHA1;
                    929:        }
                    930:        seed = chunk_create(seed_buf, seed_len);
                    931: 
                    932:        while (*trials < SECRET_KEY_TRIALS_MAX)
                    933:        {
                    934:                (*trials)++;
                    935: 
                    936:                if (!rng->get_bytes(rng, seed_len, seed_buf))
                    937:                {
                    938:                        return FALSE;
                    939:                }
                    940:                f = create_vector_from_seed(this, alg, seed);
                    941:                if (f == NULL)
                    942:                {
                    943:                        return FALSE;
                    944:                }
                    945:                if (!rng->get_bytes(rng, seed_len, seed_buf))
                    946:                {
                    947:                        free(f);
                    948:                        return FALSE;
                    949:                }
                    950:                g = create_vector_from_seed(this, alg, seed);
                    951:                if (g == NULL)
                    952:                {
                    953:                        free(f);
                    954:                        return FALSE;
                    955:                }
                    956: 
                    957:                /* Compute 2g + 1 */
                    958:                for (i = 0; i < n; i++)
                    959:                {
                    960:                        g[i] *= 2;
                    961:                }
                    962:                g[0] += 1;
                    963: 
                    964:                l2_norm = wrapped_product(f, f, n, 0) +  wrapped_product(g, g, n, 0);
                    965:                nks = nks_norm(f, g, n, this->set->kappa);
                    966: 
                    967:                switch (this->set->id)
                    968:                {
                    969:                        case BLISS_I:
                    970:                        case BLISS_II:
                    971:                        case BLISS_III:
                    972:                        case BLISS_IV:
                    973:                                DBG2(DBG_LIB, "l2 norm of s1||s2: %d, Nk(S): %u (%u max)",
                    974:                                                           l2_norm, nks, this->set->nks_max);
                    975:                                if (nks < this->set->nks_max)
                    976:                                {
                    977:                                        *s1 = f;
                    978:                                        *s2 = g;
                    979:                                        return TRUE;
                    980:                                }
                    981:                                free(f);
                    982:                                free(g);
                    983:                                break;
                    984:                        case BLISS_B_I:
                    985:                        case BLISS_B_II:
                    986:                        case BLISS_B_III:
                    987:                        case BLISS_B_IV:
                    988:                                DBG2(DBG_LIB, "l2 norm of s1||s2: %d, Nk(S): %u",
                    989:                                                           l2_norm, nks);
                    990:                                *s1 = f;
                    991:                                *s2 = g;
                    992:                                return TRUE;
                    993:                }
                    994:        }
                    995: 
                    996:        return FALSE;
                    997: }
                    998: 
                    999: /**
                   1000:  * See header.
                   1001:  */
                   1002: bliss_private_key_t *bliss_private_key_gen(key_type_t type, va_list args)
                   1003: {
                   1004:        private_bliss_private_key_t *this;
                   1005:        u_int key_size = BLISS_B_I;
                   1006:        int i, n, trials = 0;
                   1007:        uint32_t *S1, *S2, *a;
                   1008:        uint16_t q;
                   1009:        bool success = FALSE;
                   1010:        const bliss_param_set_t *set;
                   1011:        ntt_fft_t *fft;
                   1012:        rng_t *rng;
                   1013: 
                   1014:        while (TRUE)
                   1015:        {
                   1016:                switch (va_arg(args, builder_part_t))
                   1017:                {
                   1018:                        case BUILD_KEY_SIZE:
                   1019:                                key_size = va_arg(args, u_int);
                   1020:                                continue;
                   1021:                        case BUILD_END:
                   1022:                                break;
                   1023:                        default:
                   1024:                                return NULL;
                   1025:                }
                   1026:                break;
                   1027:        }
                   1028: 
                   1029:        if (lib->settings->get_bool(lib->settings, "%s.plugins.bliss.use_bliss_b",
                   1030:                                                                TRUE, lib->ns))
                   1031:        {
                   1032:                switch (key_size)
                   1033:                {
                   1034:                        case BLISS_I:
                   1035:                                key_size = BLISS_B_I;
                   1036:                                break;
                   1037:                        case BLISS_II:
                   1038:                                key_size = BLISS_B_II;
                   1039:                                break;
                   1040:                        case BLISS_III:
                   1041:                                key_size = BLISS_B_III;
                   1042:                                break;
                   1043:                        case BLISS_IV:
                   1044:                                key_size = BLISS_B_IV;
                   1045:                                break;
                   1046:                        default:
                   1047:                                break;
                   1048:                }
                   1049:        }
                   1050: 
                   1051:        /* Only BLISS or BLISS-B types I, III, or IV are currently supported */
                   1052:        set = bliss_param_set_get_by_id(key_size);
                   1053:        if (!set)
                   1054:        {
                   1055:                DBG1(DBG_LIB, "BLISS parameter set %u not supported", key_size);
                   1056:                return NULL;
                   1057:        }
                   1058: 
                   1059:        /* Some shortcuts for often used variables */
                   1060:        n = set->n;
                   1061:        q = set->q;
                   1062: 
                   1063:        if (set->fft_params->n != n || set->fft_params->q != q)
                   1064:        {
                   1065:                DBG1(DBG_LIB, "FFT parameters do not match BLISS parameters");
                   1066:                return NULL;
                   1067:        }
                   1068:        this = bliss_private_key_create_empty();
                   1069:        this->set = set;
                   1070: 
                   1071:        /* We derive the public key from the private key using the FFT */
                   1072:        fft = ntt_fft_create(set->fft_params);
                   1073: 
                   1074:        /* Some vectors needed to derive the public key */
                   1075:        S1 = malloc(n * sizeof(uint32_t));
                   1076:        S2 = malloc(n * sizeof(uint32_t));
                   1077:        a  = malloc(n * sizeof(uint32_t));
                   1078:        this->A  = malloc(n * sizeof(uint32_t));
                   1079:        this->Ar = malloc(n * sizeof(uint32_t));
                   1080: 
                   1081:        /* Instantiate a true random generator */
                   1082:        rng = lib->crypto->create_rng(lib->crypto, RNG_TRUE);
                   1083: 
                   1084:        /* Loop until we have an invertible polynomial s1 */
                   1085:        do
                   1086:        {
                   1087:                if (!create_secret(this, rng, &this->s1, &this->s2, &trials))
                   1088:                {
                   1089:                        break;
                   1090:                }
                   1091: 
                   1092:                /* Convert signed arrays to unsigned arrays before FFT */
                   1093:                for (i = 0; i < n; i++)
                   1094:                {
                   1095:                        S1[i] = (this->s1[i] < 0) ? this->s1[i] + q :  this->s1[i];
                   1096:                        S2[i] = (this->s2[i] > 0) ? q - this->s2[i] : -this->s2[i];
                   1097:                }
                   1098:                fft->transform(fft, S1, S1, FALSE);
                   1099:                fft->transform(fft, S2, S2, FALSE);
                   1100: 
                   1101:                success = TRUE;
                   1102: 
                   1103:                for (i = 0; i < n; i++)
                   1104:                {
                   1105:                        if (S1[i] == 0)
                   1106:                        {
                   1107:                                DBG1(DBG_LIB, "S1[%d] is zero - s1 is not invertible", i);
                   1108:                                free(this->s1);
                   1109:                                free(this->s2);
                   1110:                                this->s1 = NULL;
                   1111:                                this->s2 = NULL;
                   1112:                                success = FALSE;
                   1113:                                break;
                   1114:                        }
                   1115:                        this->Ar[i] = invert(this, S1[i]);
                   1116:                        this->Ar[i] = ntt_fft_mreduce(S2[i] * this->Ar[i], set->fft_params);
                   1117:                        this->A[i]  = ntt_fft_mreduce(this->Ar[i], set->fft_params);
                   1118:                }
                   1119:        }
                   1120:        while (!success && trials < SECRET_KEY_TRIALS_MAX);
                   1121: 
                   1122:        DBG1(DBG_LIB, "secret key generation %s after %d trial%s",
                   1123:                 success ? "succeeded" : "failed", trials, (trials == 1) ? "" : "s");
                   1124: 
                   1125:        if (success)
                   1126:        {
                   1127:                fft->transform(fft, this->Ar, a, TRUE);
                   1128: 
                   1129:                DBG4(DBG_LIB, "   i   f   g     a     F     G     A");
                   1130:                for (i = 0; i < n; i++)
                   1131:                {
                   1132:                        DBG4(DBG_LIB, "%4d %3d %3d %5u %5u %5u %5u",
                   1133:                                                  i, this->s1[i], this->s2[i],
                   1134:                                                  ntt_fft_mreduce(a[i], set->fft_params),
                   1135:                                                  S1[i], S2[i], this->A[i]);
                   1136:                }
                   1137:        }
                   1138:        else
                   1139:        {
                   1140:                destroy(this);
                   1141:        }
                   1142: 
                   1143:        /* Cleanup */
                   1144:        fft->destroy(fft);
                   1145:        rng->destroy(rng);
                   1146:        memwipe(S1, n * sizeof(uint32_t));
                   1147:        memwipe(S2, n * sizeof(uint32_t));
                   1148:        free(S1);
                   1149:        free(S2);
                   1150:        free(a);
                   1151: 
                   1152:        return success ? &this->public : NULL;
                   1153: }
                   1154: 
                   1155: /**
                   1156:  * ASN.1 definition of a BLISS private key
                   1157:  */
                   1158: static const asn1Object_t privkeyObjects[] = {
                   1159:        { 0, "BLISSPrivateKey",         ASN1_SEQUENCE,   ASN1_NONE }, /*  0 */
                   1160:        { 1,   "keyType",                       ASN1_OID,        ASN1_BODY }, /*  1 */
                   1161:        { 1,   "public",                        ASN1_BIT_STRING, ASN1_BODY }, /*  2 */
                   1162:        { 1,   "secret1",                       ASN1_BIT_STRING, ASN1_BODY }, /*  3 */
                   1163:        { 1,   "secret2",                       ASN1_BIT_STRING, ASN1_BODY }, /*  4 */
                   1164:        { 0, "exit",                            ASN1_EOC,        ASN1_EXIT }
                   1165: };
                   1166: #define PRIV_KEY_TYPE                  1
                   1167: #define PRIV_KEY_PUBLIC                        2
                   1168: #define PRIV_KEY_SECRET1               3
                   1169: #define PRIV_KEY_SECRET2               4
                   1170: 
                   1171: /**
                   1172:  * See header.
                   1173:  */
                   1174: bliss_private_key_t *bliss_private_key_load(key_type_t type, va_list args)
                   1175: {
                   1176:        private_bliss_private_key_t *this;
                   1177:        chunk_t key = chunk_empty, object;
                   1178:        bliss_bitpacker_t *packer;
                   1179:        asn1_parser_t *parser;
                   1180:        size_t s_bits = 0;
                   1181:        int8_t s, s_min = 0, s_max = 0;
                   1182:        uint32_t s_sign = 0x02, s_mask = 0xfffffffc, value, r2;
                   1183:        bool success = FALSE;
                   1184:        int objectID, oid, i;
                   1185: 
                   1186:        while (TRUE)
                   1187:        {
                   1188:                switch (va_arg(args, builder_part_t))
                   1189:                {
                   1190:                        case BUILD_BLOB_ASN1_DER:
                   1191:                                key = va_arg(args, chunk_t);
                   1192:                                continue;
                   1193:                        case BUILD_END:
                   1194:                                break;
                   1195:                        default:
                   1196:                                return NULL;
                   1197:                }
                   1198:                break;
                   1199:        }
                   1200: 
                   1201:        if (key.len == 0)
                   1202:        {
                   1203:                return NULL;
                   1204:        }
                   1205:        this = bliss_private_key_create_empty();
                   1206: 
                   1207:        parser = asn1_parser_create(privkeyObjects, key);
                   1208:        parser->set_flags(parser, FALSE, TRUE);
                   1209: 
                   1210:        while (parser->iterate(parser, &objectID, &object))
                   1211:        {
                   1212:                switch (objectID)
                   1213:                {
                   1214:                        case PRIV_KEY_TYPE:
                   1215:                                oid = asn1_known_oid(object);
                   1216:                                if (oid == OID_UNKNOWN)
                   1217:                                {
                   1218:                                        goto end;
                   1219:                                }
                   1220:                                this->set = bliss_param_set_get_by_oid(oid);
                   1221:                                if (this->set == NULL)
                   1222:                                {
                   1223:                                        goto end;
                   1224:                                }
                   1225:                                if (lib->settings->get_bool(lib->settings,
                   1226:                                                        "%s.plugins.bliss.use_bliss_b",TRUE, lib->ns))
                   1227:                                {
                   1228:                                        switch (this->set->id)
                   1229:                                        {
                   1230:                                                case BLISS_I:
                   1231:                                                        this->set = bliss_param_set_get_by_id(BLISS_B_I);
                   1232:                                                        break;
                   1233:                                                case BLISS_III:
                   1234:                                                        this->set = bliss_param_set_get_by_id(BLISS_B_III);
                   1235:                                                        break;
                   1236:                                                case BLISS_IV:
                   1237:                                                        this->set = bliss_param_set_get_by_id(BLISS_B_IV);
                   1238:                                                        break;
                   1239:                                                default:
                   1240:                                                        break;
                   1241:                                        }
                   1242:                                }
                   1243:                                if (this->set->non_zero2)
                   1244:                                {
                   1245:                                        s_min = -2;
                   1246:                                        s_max =  2;
                   1247:                                        s_bits = 3;
                   1248:                                }
                   1249:                                else
                   1250:                                {
                   1251:                                        s_min = -1;
                   1252:                                        s_max =  1;
                   1253:                                        s_bits = 2;
                   1254:                                }
                   1255:                                s_sign = 1 << (s_bits - 1);
                   1256:                                s_mask = ((1 << (32 - s_bits)) - 1) << s_bits;
                   1257:                                break;
                   1258:                        case PRIV_KEY_PUBLIC:
                   1259:                                if (!bliss_public_key_from_asn1(object, this->set, &this->A))
                   1260:                                {
                   1261:                                        goto end;
                   1262:                                }
                   1263:                                this->Ar = malloc(this->set->n * sizeof(uint32_t));
                   1264:                                r2 = this->set->fft_params->r2;
                   1265: 
                   1266:                                for (i = 0; i < this->set->n; i++)
                   1267:                                {
                   1268:                                        this->Ar[i] = ntt_fft_mreduce(this->A[i] * r2,
                   1269:                                                                                                  this->set->fft_params);
                   1270:                                }
                   1271:                                break;
                   1272:                        case PRIV_KEY_SECRET1:
                   1273:                                if (object.len != 1 + (s_bits * this->set->n + 7)/8)
                   1274:                                {
                   1275:                                        goto end;
                   1276:                                }
                   1277:                                this->s1 = malloc(this->set->n);
                   1278: 
                   1279:                                /* Skip unused bits octet */
                   1280:                                object = chunk_skip(object, 1);
                   1281:                                packer = bliss_bitpacker_create_from_data(object);
                   1282:                                for (i = 0; i < this->set->n; i++)
                   1283:                                {
                   1284:                                        packer->read_bits(packer, &value, s_bits);
                   1285:                                        s = (value & s_sign) ? value | s_mask : value;
                   1286:                                        if (s < s_min || s > s_max)
                   1287:                                        {
                   1288:                                                packer->destroy(packer);
                   1289:                                                goto end;
                   1290:                                        }
                   1291:                                        this->s1[i] = s;
                   1292:                                }
                   1293:                                packer->destroy(packer);
                   1294:                                break;
                   1295:                        case PRIV_KEY_SECRET2:
                   1296:                                if (object.len != 1 + (s_bits * this->set->n + 7)/8)
                   1297:                                {
                   1298:                                        goto end;
                   1299:                                }
                   1300:                                this->s2 = malloc(this->set->n);
                   1301: 
                   1302:                                /* Skip unused bits octet */
                   1303:                                object = chunk_skip(object, 1);
                   1304:                                packer = bliss_bitpacker_create_from_data(object);
                   1305:                                for (i = 0; i < this->set->n; i++)
                   1306:                                {
                   1307:                                        packer->read_bits(packer, &value, s_bits);
                   1308:                                        s = (value & s_sign) ? value | s_mask : value;
                   1309:                                        if (s < s_min || s > s_max)
                   1310:                                        {
                   1311:                                                packer->destroy(packer);
                   1312:                                                goto end;
                   1313:                                        }
                   1314:                                        this->s2[i] = 2 * s;
                   1315:                                        if (i == 0)
                   1316:                                        {
                   1317:                                                this->s2[0] += 1;
                   1318:                                        }
                   1319:                                }
                   1320:                                packer->destroy(packer);
                   1321:                                break;
                   1322:                }
                   1323:        }
                   1324:        success = parser->success(parser);
                   1325: 
                   1326: end:
                   1327:        parser->destroy(parser);
                   1328:        if (!success)
                   1329:        {
                   1330:                destroy(this);
                   1331:                return NULL;
                   1332:        }
                   1333: 
                   1334:        return &this->public;
                   1335: }
                   1336: 

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