2 * Copyright (C) 2014-2015 Andreas Steffen
3 * HSR Hochschule fuer Technik Rapperswil
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>.
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
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 "bliss_fft.h"
25 #include <crypto/mgf1/mgf1_bitspender.h>
26 #include <asn1/asn1.h>
27 #include <asn1/asn1_parser.h>
33 typedef struct private_bliss_private_key_t private_bliss_private_key_t
;
35 #define SECRET_KEY_TRIALS_MAX 50
38 * Private data of a bliss_private_key_t object.
40 struct private_bliss_private_key_t
{
42 * Public interface for this signer.
44 bliss_private_key_t
public;
47 * BLISS signature parameter set
49 bliss_param_set_t
*set
;
52 * BLISS secret key S1 (coefficients of polynomial f)
57 * BLISS secret key S2 (coefficients of polynomial 2g + 1)
62 * NTT of BLISS public key a (coefficients of polynomial (2g + 1)/f)
72 METHOD(private_key_t
, get_type
, key_type_t
,
73 private_bliss_private_key_t
*this)
79 * Multiply secret vector s with binary challenge vector c
81 static void multiply_by_c(int8_t *s
, int n
, uint16_t *c_indices
,
82 uint16_t kappa
, int32_t *product
)
86 for (i
= 0; i
< n
; i
++)
90 for (j
= 0; j
< kappa
; j
++)
95 product
[i
] -= s
[i
- index
+ n
];
99 product
[i
] += s
[i
- index
];
106 * BLISS-B GreedySC algorithm
108 static void greedy_sc(int8_t *s1
, int8_t *s2
, int n
, uint16_t *c_indices
,
109 uint16_t kappa
, int32_t *v1
, int32_t *v2
)
114 for (i
= 0; i
< n
; i
++)
118 for (j
= 0; j
< kappa
; j
++)
120 index
= c_indices
[j
];
123 for (i
= 0; i
< index
; i
++)
125 sign
-= (v1
[i
] * s1
[i
- index
+ n
] + v2
[i
] * s2
[i
- index
+ n
]);
127 for (i
= index
; i
< n
; i
++)
129 sign
+= (v1
[i
] * s1
[i
- index
] + v2
[i
] * s2
[i
- index
]);
131 for (i
= 0; i
< index
; i
++)
135 v1
[i
] += s1
[i
- index
+ n
];
136 v2
[i
] += s2
[i
- index
+ n
];
140 v1
[i
] -= s1
[i
- index
+ n
];
141 v2
[i
] -= s2
[i
- index
+ n
];
144 for (i
= index
; i
< n
; i
++)
148 v1
[i
] -= s1
[i
- index
];
149 v2
[i
] -= s2
[i
- index
];
153 v1
[i
] += s1
[i
- index
];
154 v2
[i
] += s2
[i
- index
];
161 * Compute a BLISS signature
163 static bool sign_bliss(private_bliss_private_key_t
*this, hash_algorithm_t alg
,
164 chunk_t data
, chunk_t
*signature
)
167 bliss_signature_t
*sig
;
168 bliss_sampler_t
*sampler
= NULL
;
171 hash_algorithm_t mgf1_alg
, oracle_alg
;
172 size_t mgf1_seed_len
;
173 uint8_t mgf1_seed_buf
[HASH_SIZE_SHA512
], data_hash_buf
[HASH_SIZE_SHA512
];
174 chunk_t mgf1_seed
, data_hash
;
175 uint16_t q
, q2
, p
, p2
, *c_indices
, tests
= 0;
177 int32_t *y1
, *y2
, *z1
, *z2
, *u
, *s1c
, *s2c
;
178 int32_t y1_min
= 0, y1i
, y1_max
= 0, y2_min
= 0, y2i
, y2_max
= 0;
179 int32_t scalar
, norm
, ui
;
180 int16_t *ud
, *uz2d
, *z2d
, value
;
182 double mean1
= 0, mean2
= 0, sigma1
= 0, sigma2
= 0;
183 bool accepted
, positive
, success
= FALSE
, use_bliss_b
;
185 /* Initialize signature */
186 *signature
= chunk_empty
;
188 /* Create data hash using configurable hash algorithm */
189 hasher
= lib
->crypto
->create_hasher(lib
->crypto
, alg
);
194 data_hash
= chunk_create(data_hash_buf
, hasher
->get_hash_size(hasher
));
196 if (!hasher
->get_hash(hasher
, data
, data_hash_buf
))
198 hasher
->destroy(hasher
);
201 hasher
->destroy(hasher
);
203 /* Set MGF1 hash algorithm and seed length based on security strength */
204 if (this->set
->strength
> 160)
206 mgf1_alg
= HASH_SHA256
;
207 mgf1_seed_len
= HASH_SIZE_SHA256
;
211 mgf1_alg
= HASH_SHA1
;
212 mgf1_seed_len
= HASH_SIZE_SHA1
;
214 mgf1_seed
= chunk_create(mgf1_seed_buf
, mgf1_seed_len
);
216 rng
= lib
->crypto
->create_rng(lib
->crypto
, RNG_STRONG
);
222 /* MGF1 hash algorithm to be used for random oracle */
223 oracle_alg
= HASH_SHA512
;
225 /* Initialize a couple of needed variables */
231 ay
= malloc(n
* sizeof(uint32_t));
232 z2
= malloc(n
* sizeof(int32_t));
233 s1c
= malloc(n
* sizeof(int32_t));
234 s2c
= malloc(n
* sizeof(int32_t));
235 u
= malloc(n
* sizeof(int32_t));
236 uz2d
= malloc(n
* sizeof(int16_t));
238 sig
= bliss_signature_create(this->set
);
239 sig
->get_parameters(sig
, &z1
, &z2d
, &c_indices
);
244 fft
= bliss_fft_create(this->set
->fft_params
);
246 /* Use of the enhanced BLISS-B signature algorithm? */
247 switch (this->set
->id
)
268 if (!rng
->get_bytes(rng
, mgf1_seed_len
, mgf1_seed_buf
))
274 sampler
= bliss_sampler_create(mgf1_alg
, mgf1_seed
, this->set
);
280 /* Gaussian sampling for vectors y1 and y2 */
281 for (i
= 0; i
< n
; i
++)
283 if (!sampler
->gaussian(sampler
, &y1i
) ||
284 !sampler
->gaussian(sampler
, &y2i
))
291 /* Collect statistical data on rejection sampling */
294 y1_min
= y1_max
= y1i
;
295 y2_min
= y2_max
= y2i
;
303 else if (y1i
> y1_max
)
311 else if (y2i
> y2_max
)
321 ay
[i
] = y1i
< 0 ? q
+ y1i
: y1i
;
324 /* Compute statistics on vectors y1 and y2 */
329 sigma2
-= mean1
* mean1
;
330 sigma2
-= mean2
* mean2
;
331 DBG2(DBG_LIB
, "y1 = %d..%d (sigma2 = %5.0f, mean = %4.1f)",
332 y1_min
, y1_max
, sigma1
, mean1
);
333 DBG2(DBG_LIB
, "y2 = %d..%d (sigma2 = %5.0f, mean = %4.1f)",
334 y2_min
, y2_max
, sigma2
, mean2
);
336 fft
->transform(fft
, ay
, ay
, FALSE
);
338 for (i
= 0; i
< n
; i
++)
340 ay
[i
] = (this->A
[i
] * ay
[i
]) % q
;
342 fft
->transform(fft
, ay
, ay
, TRUE
);
344 for (i
= 0; i
< n
; i
++)
346 ui
= 2 * this->set
->q2_inv
* (int32_t)ay
[i
] + y2
[i
];
347 u
[i
] = ((ui
< 0) ? q2
+ ui
: ui
) % q2
;
349 bliss_utils_round_and_drop(this->set
, u
, ud
);
351 /* Detailed debugging information */
352 DBG3(DBG_LIB
, " i u[i] ud[i]");
353 for (i
= 0; i
< n
; i
++)
355 DBG3(DBG_LIB
, "%3d %6d %4d", i
, u
[i
], ud
[i
]);
358 if (!bliss_utils_generate_c(oracle_alg
, data_hash
, ud
, this->set
,
366 /* Compute v = (s1c, s2c) with the GreedySC algorithm */
367 greedy_sc(this->s1
, this->s2
, n
, c_indices
, this->set
->kappa
,
370 /* Compute norm = ||v||^2 = ||Sc'||^2 */
371 norm
= bliss_utils_scalar_product(s1c
, s1c
, n
) +
372 bliss_utils_scalar_product(s2c
, s2c
, n
);
374 /* Just in case. ||v||^2 <= P_max should always be fulfilled */
375 if (norm
> this->set
->p_max
)
383 multiply_by_c(this->s1
, n
, c_indices
, this->set
->kappa
, s1c
);
384 multiply_by_c(this->s2
, n
, c_indices
, this->set
->kappa
, s2c
);
386 /* Compute norm = |Sc||^2 */
387 norm
= bliss_utils_scalar_product(s1c
, s1c
, n
) +
388 bliss_utils_scalar_product(s2c
, s2c
, n
);
391 if (!sampler
->bernoulli_exp(sampler
, this->set
->M
- norm
, &accepted
))
397 DBG2(DBG_LIB
, "norm2(s1*c') + norm2(s2*c') = %u (%u max), %s",
398 norm
, this->set
->p_max
, accepted ?
"accepted" : "rejected");
403 DBG2(DBG_LIB
, "norm2(s1*c) + norm2(s2*c) = %u, %s",
404 norm
, accepted ?
"accepted" : "rejected");
412 if (!sampler
->sign(sampler
, &positive
))
416 for (i
= 0; i
< n
; i
++)
420 z1
[i
] = y1
[i
] + s1c
[i
];
421 z2
[i
] = y2
[i
] + s2c
[i
];
425 z1
[i
] = y1
[i
] - s1c
[i
];
426 z2
[i
] = y2
[i
] - s2c
[i
];
429 /* Reject with probability 1/cosh(scalar/sigma^2) */
430 scalar
= bliss_utils_scalar_product(z1
, s1c
, n
) +
431 bliss_utils_scalar_product(z2
, s2c
, n
);
433 if (!sampler
->bernoulli_cosh(sampler
, scalar
, &accepted
))
437 DBG2(DBG_LIB
, "scalar(z1,s1*c) + scalar(z2,s2*c) = %d, %s",
438 scalar
, accepted ?
"accepted" : "rejected");
444 /* Compute z2 with dropped bits */
445 for (i
= 0; i
< n
; i
++)
457 bliss_utils_round_and_drop(this->set
, u
, uz2d
);
459 for (i
= 0; i
< n
; i
++)
461 value
= ud
[i
] - uz2d
[i
];
473 if (!bliss_utils_check_norms(this->set
, z1
, z2d
))
478 *signature
= sig
->get_encoding(sig
);
479 if (signature
->len
== 0)
481 DBG1(DBG_LIB
, "inefficient Huffman coding of signature");
484 DBG2(DBG_LIB
, "signature generation needed %u round%s", tests
,
485 (tests
== 1) ?
"" : "s");
496 memwipe(s1c
, n
* sizeof(int32_t));
497 memwipe(s2c
, n
* sizeof(int32_t));
508 METHOD(private_key_t
, sign
, bool,
509 private_bliss_private_key_t
*this, signature_scheme_t scheme
,
510 chunk_t data
, chunk_t
*signature
)
514 case SIGN_BLISS_WITH_SHA2_256
:
515 return sign_bliss(this, HASH_SHA256
, data
, signature
);
516 case SIGN_BLISS_WITH_SHA2_384
:
517 return sign_bliss(this, HASH_SHA384
, data
, signature
);
518 case SIGN_BLISS_WITH_SHA2_512
:
519 return sign_bliss(this, HASH_SHA512
, data
, signature
);
520 case SIGN_BLISS_WITH_SHA3_256
:
521 return sign_bliss(this, HASH_SHA3_256
, data
, signature
);
522 case SIGN_BLISS_WITH_SHA3_384
:
523 return sign_bliss(this, HASH_SHA3_384
, data
, signature
);
524 case SIGN_BLISS_WITH_SHA3_512
:
525 return sign_bliss(this, HASH_SHA3_512
, data
, signature
);
527 DBG1(DBG_LIB
, "signature scheme %N not supported with BLISS",
528 signature_scheme_names
, scheme
);
533 METHOD(private_key_t
, decrypt
, bool,
534 private_bliss_private_key_t
*this, encryption_scheme_t scheme
,
535 chunk_t crypto
, chunk_t
*plain
)
537 DBG1(DBG_LIB
, "encryption scheme %N not supported",
538 encryption_scheme_names
, scheme
);
542 METHOD(private_key_t
, get_keysize
, int,
543 private_bliss_private_key_t
*this)
545 return this->set
->strength
;
548 METHOD(private_key_t
, get_public_key
, public_key_t
*,
549 private_bliss_private_key_t
*this)
551 public_key_t
*public;
554 pubkey
= bliss_public_key_info_encode(this->set
->oid
, this->A
, this->set
);
555 public = lib
->creds
->create(lib
->creds
, CRED_PUBLIC_KEY
, KEY_BLISS
,
556 BUILD_BLOB_ASN1_DER
, pubkey
, BUILD_END
);
562 METHOD(private_key_t
, get_encoding
, bool,
563 private_bliss_private_key_t
*this, cred_encoding_type_t type
,
568 case PRIVKEY_ASN1_DER
:
571 chunk_t s1
, s2
, pubkey
;
572 bliss_bitpacker_t
*packer
;
578 pubkey
= bliss_public_key_encode(this->A
, this->set
);
580 /* Use either 2 or 3 bits per array element */
581 s_bits
= 2 + (this->set
->non_zero2
> 0);
583 /* Encode secret s1 */
584 packer
= bliss_bitpacker_create(s_bits
* this->set
->n
);
585 for (i
= 0; i
< this->set
->n
; i
++)
587 packer
->write_bits(packer
, this->s1
[i
], s_bits
);
589 s1
= packer
->extract_buf(packer
);
590 packer
->destroy(packer
);
592 /* Encode secret s2 */
593 packer
= bliss_bitpacker_create(s_bits
* this->set
->n
);
594 for (i
= 0; i
< this->set
->n
; i
++)
602 packer
->write_bits(packer
, value
, s_bits
);
604 s2
= packer
->extract_buf(packer
);
605 packer
->destroy(packer
);
607 *encoding
= asn1_wrap(ASN1_SEQUENCE
, "mmss",
608 asn1_build_known_oid(this->set
->oid
),
609 asn1_bitstring("m", pubkey
),
610 asn1_bitstring("m", s1
),
611 asn1_bitstring("m", s2
)
613 if (type
== PRIVKEY_PEM
)
615 chunk_t asn1_encoding
= *encoding
;
617 success
= lib
->encoding
->encode(lib
->encoding
, PRIVKEY_PEM
,
618 NULL
, encoding
, CRED_PART_BLISS_PRIV_ASN1_DER
,
619 asn1_encoding
, CRED_PART_END
);
620 chunk_clear(&asn1_encoding
);
629 METHOD(private_key_t
, get_fingerprint
, bool,
630 private_bliss_private_key_t
*this, cred_encoding_type_t type
, chunk_t
*fp
)
634 if (lib
->encoding
->get_cache(lib
->encoding
, type
, this, fp
))
638 success
= bliss_public_key_fingerprint(this->set
->oid
, this->A
,
639 this->set
, type
, fp
);
642 lib
->encoding
->cache(lib
->encoding
, type
, this, *fp
);
647 METHOD(private_key_t
, get_ref
, private_key_t
*,
648 private_bliss_private_key_t
*this)
651 return &this->public.key
;
654 METHOD(private_key_t
, destroy
, void,
655 private_bliss_private_key_t
*this)
657 if (ref_put(&this->ref
))
659 lib
->encoding
->clear_cache(lib
->encoding
, this);
662 memwipe(this->s1
, this->set
->n
* sizeof(int8_t));
667 memwipe(this->s2
, this->set
->n
* sizeof(int8_t));
676 * Internal generic constructor
678 static private_bliss_private_key_t
*bliss_private_key_create_empty(void)
680 private_bliss_private_key_t
*this;
685 .get_type
= _get_type
,
688 .get_keysize
= _get_keysize
,
689 .get_public_key
= _get_public_key
,
690 .equals
= private_key_equals
,
691 .belongs_to
= private_key_belongs_to
,
692 .get_fingerprint
= _get_fingerprint
,
693 .has_fingerprint
= private_key_has_fingerprint
,
694 .get_encoding
= _get_encoding
,
705 * Compute the scalar product of a vector x with a negative wrapped vector y
707 static int16_t wrapped_product(int8_t *x
, int8_t *y
, int n
, int shift
)
712 for (i
= 0; i
< n
- shift
; i
++)
714 product
+= x
[i
] * y
[i
+ shift
];
716 for (i
= n
- shift
; i
< n
; i
++)
718 product
-= x
[i
] * y
[i
+ shift
- n
];
724 * Apply a negative wrapped rotation to a vector x
726 static void wrap(int16_t *x
, int n
, int shift
, int16_t *x_wrapped
)
730 for (i
= 0; i
< n
- shift
; i
++)
732 x_wrapped
[i
+ shift
] = x
[i
];
734 for (i
= n
- shift
; i
< n
; i
++)
736 x_wrapped
[i
+ shift
- n
] = -x
[i
];
741 * int16_t compare function needed for qsort()
743 static int compare(const int16_t *a
, const int16_t *b
)
745 int16_t temp
= *a
- *b
;
762 * Compute the Nk(S) norm of S = (s1, s2)
764 static uint32_t nks_norm(int8_t *s1
, int8_t *s2
, int n
, uint16_t kappa
)
766 int16_t t
[n
], t_wrapped
[n
], max_kappa
[n
];
770 for (i
= 0; i
< n
; i
++)
772 t
[i
] = wrapped_product(s1
, s1
, n
, i
) + wrapped_product(s2
, s2
, n
, i
);
775 for (i
= 0; i
< n
; i
++)
777 wrap(t
, n
, i
, t_wrapped
);
778 qsort(t_wrapped
, n
, sizeof(int16_t), (__compar_fn_t
)compare
);
781 for (j
= 1; j
<= kappa
; j
++)
783 max_kappa
[i
] += t_wrapped
[n
- j
];
786 qsort(max_kappa
, n
, sizeof(int16_t), (__compar_fn_t
)compare
);
788 for (i
= 1; i
<= kappa
; i
++)
790 nks
+= max_kappa
[n
- i
];
796 * Compute the inverse x1 of x modulo q as x^(-1) = x^(q-2) mod q
798 static uint32_t invert(uint32_t x
, uint16_t q
)
805 x1
= (q2
& 1) ? x
: 1;
809 while ((q2
& (1 << i_max
)) == 0)
813 for (i
= 1; i
<= i_max
; i
++)
827 * Create a vector with sparse and small coefficients from seed
829 static int8_t* create_vector_from_seed(private_bliss_private_key_t
*this,
830 hash_algorithm_t alg
, chunk_t seed
)
832 mgf1_bitspender_t
*bitspender
;
833 uint32_t index
, sign
;
837 bitspender
= mgf1_bitspender_create(alg
, seed
, FALSE
);
843 vector
= malloc(sizeof(int8_t) * this->set
->n
);
844 memset(vector
, 0x00, this->set
->n
);
846 non_zero
= this->set
->non_zero1
;
849 if (!bitspender
->get_bits(bitspender
, this->set
->n_bits
, &index
))
854 if (vector
[index
] != 0)
859 if (!bitspender
->get_bits(bitspender
, 1, &sign
))
864 vector
[index
] = sign ?
1 : -1;
868 non_zero
= this->set
->non_zero2
;
871 if (!bitspender
->get_bits(bitspender
, this->set
->n_bits
, &index
))
876 if (vector
[index
] != 0)
881 if (!bitspender
->get_bits(bitspender
, 1, &sign
))
886 vector
[index
] = sign ?
2 : -2;
889 bitspender
->destroy(bitspender
);
895 * Generate the secret key S = (s1, s2) fulfilling the Nk(S) norm
897 static bool create_secret(private_bliss_private_key_t
*this, rng_t
*rng
,
898 int8_t **s1
, int8_t **s2
, int *trials
)
900 uint8_t seed_buf
[32];
902 uint32_t l2_norm
, nks
;
906 hash_algorithm_t alg
;
912 /* Set MGF1 hash algorithm and seed length based on security strength */
913 if (this->set
->strength
> 160)
916 seed_len
= HASH_SIZE_SHA256
;
921 seed_len
= HASH_SIZE_SHA1
;
923 seed
= chunk_create(seed_buf
, seed_len
);
925 while (*trials
< SECRET_KEY_TRIALS_MAX
)
929 if (!rng
->get_bytes(rng
, seed_len
, seed_buf
))
933 f
= create_vector_from_seed(this, alg
, seed
);
938 if (!rng
->get_bytes(rng
, seed_len
, seed_buf
))
943 g
= create_vector_from_seed(this, alg
, seed
);
951 for (i
= 0; i
< n
; i
++)
957 l2_norm
= wrapped_product(f
, f
, n
, 0) + wrapped_product(g
, g
, n
, 0);
958 nks
= nks_norm(f
, g
, n
, this->set
->kappa
);
960 switch (this->set
->id
)
966 DBG2(DBG_LIB
, "l2 norm of s1||s2: %d, Nk(S): %u (%u max)",
967 l2_norm
, nks
, this->set
->nks_max
);
968 if (nks
< this->set
->nks_max
)
981 DBG2(DBG_LIB
, "l2 norm of s1||s2: %d, Nk(S): %u",
995 bliss_private_key_t
*bliss_private_key_gen(key_type_t type
, va_list args
)
997 private_bliss_private_key_t
*this;
998 u_int key_size
= BLISS_B_I
;
999 int i
, n
, trials
= 0;
1000 uint32_t *S1
, *S2
, *a
;
1002 bool success
= FALSE
;
1003 bliss_param_set_t
*set
;
1009 switch (va_arg(args
, builder_part_t
))
1011 case BUILD_KEY_SIZE
:
1012 key_size
= va_arg(args
, u_int
);
1022 if (lib
->settings
->get_bool(lib
->settings
, "%s.plugins.bliss.use_bliss_b",
1028 key_size
= BLISS_B_I
;
1031 key_size
= BLISS_B_II
;
1034 key_size
= BLISS_B_III
;
1037 key_size
= BLISS_B_IV
;
1044 /* Only BLISS or BLISS-B types I, III, or IV are currently supported */
1045 set
= bliss_param_set_get_by_id(key_size
);
1048 DBG1(DBG_LIB
, "BLISS parameter set %u not supported", key_size
);
1052 /* Some shortcuts for often used variables */
1056 if (set
->fft_params
->n
!= n
|| set
->fft_params
->q
!= q
)
1058 DBG1(DBG_LIB
, "FFT parameters do not match BLISS parameters");
1061 this = bliss_private_key_create_empty();
1064 /* We derive the public key from the private key using the FFT */
1065 fft
= bliss_fft_create(set
->fft_params
);
1067 /* Some vectors needed to derive the publi key */
1068 S1
= malloc(n
* sizeof(uint32_t));
1069 S2
= malloc(n
* sizeof(uint32_t));
1070 a
= malloc(n
* sizeof(uint32_t));
1071 this->A
= malloc(n
* sizeof(uint32_t));
1073 /* Instantiate a true random generator */
1074 rng
= lib
->crypto
->create_rng(lib
->crypto
, RNG_TRUE
);
1076 /* Loop until we have an invertible polynomial s1 */
1079 if (!create_secret(this, rng
, &this->s1
, &this->s2
, &trials
))
1084 /* Convert signed arrays to unsigned arrays before FFT */
1085 for (i
= 0; i
< n
; i
++)
1087 S1
[i
] = (this->s1
[i
] < 0) ?
this->s1
[i
] + q
: this->s1
[i
];
1088 S2
[i
] = (this->s2
[i
] > 0) ? q
- this->s2
[i
] : -this->s2
[i
];
1090 fft
->transform(fft
, S1
, S1
, FALSE
);
1091 fft
->transform(fft
, S2
, S2
, FALSE
);
1094 for (i
= 0; i
< n
; i
++)
1098 DBG1(DBG_LIB
, "S1[%d] is zero - s1 is not invertible", i
);
1106 this->A
[i
] = invert(S1
[i
], q
);
1107 this->A
[i
] = (S2
[i
] * this->A
[i
]) % q
;
1110 while (!success
&& trials
< SECRET_KEY_TRIALS_MAX
);
1112 DBG1(DBG_LIB
, "secret key generation %s after %d trial%s",
1113 success ?
"succeeded" : "failed", trials
, (trials
== 1) ?
"" : "s");
1117 fft
->transform(fft
, this->A
, a
, TRUE
);
1119 DBG4(DBG_LIB
, " i f g a F G A");
1120 for (i
= 0; i
< n
; i
++)
1122 DBG4(DBG_LIB
, "%4d %3d %3d %5u %5u %5u %5u",
1123 i
, this->s1
[i
], this->s2
[i
], a
[i
], S1
[i
], S2
[i
], this->A
[i
]);
1134 memwipe(S1
, n
* sizeof(uint32_t));
1135 memwipe(S2
, n
* sizeof(uint32_t));
1140 return success ?
&this->public : NULL
;
1144 * ASN.1 definition of a BLISS private key
1146 static const asn1Object_t privkeyObjects
[] = {
1147 { 0, "BLISSPrivateKey", ASN1_SEQUENCE
, ASN1_NONE
}, /* 0 */
1148 { 1, "keyType", ASN1_OID
, ASN1_BODY
}, /* 1 */
1149 { 1, "public", ASN1_BIT_STRING
, ASN1_BODY
}, /* 2 */
1150 { 1, "secret1", ASN1_BIT_STRING
, ASN1_BODY
}, /* 3 */
1151 { 1, "secret2", ASN1_BIT_STRING
, ASN1_BODY
}, /* 4 */
1152 { 0, "exit", ASN1_EOC
, ASN1_EXIT
}
1154 #define PRIV_KEY_TYPE 1
1155 #define PRIV_KEY_PUBLIC 2
1156 #define PRIV_KEY_SECRET1 3
1157 #define PRIV_KEY_SECRET2 4
1162 bliss_private_key_t
*bliss_private_key_load(key_type_t type
, va_list args
)
1164 private_bliss_private_key_t
*this;
1165 chunk_t key
= chunk_empty
, object
;
1166 bliss_bitpacker_t
*packer
;
1167 asn1_parser_t
*parser
;
1169 int8_t s
, s_min
= 0, s_max
= 0;
1170 uint32_t s_sign
= 0x02, s_mask
= 0xfffffffc, value
;
1171 bool success
= FALSE
;
1172 int objectID
, oid
, i
;
1176 switch (va_arg(args
, builder_part_t
))
1178 case BUILD_BLOB_ASN1_DER
:
1179 key
= va_arg(args
, chunk_t
);
1193 this = bliss_private_key_create_empty();
1195 parser
= asn1_parser_create(privkeyObjects
, key
);
1196 parser
->set_flags(parser
, FALSE
, TRUE
);
1198 while (parser
->iterate(parser
, &objectID
, &object
))
1203 oid
= asn1_known_oid(object
);
1204 if (oid
== OID_UNKNOWN
)
1208 this->set
= bliss_param_set_get_by_oid(oid
);
1209 if (this->set
== NULL
)
1213 if (lib
->settings
->get_bool(lib
->settings
,
1214 "%s.plugins.bliss.use_bliss_b",TRUE
, lib
->ns
))
1216 switch (this->set
->id
)
1219 this->set
= bliss_param_set_get_by_id(BLISS_B_I
);
1222 this->set
= bliss_param_set_get_by_id(BLISS_B_III
);
1225 this->set
= bliss_param_set_get_by_id(BLISS_B_IV
);
1231 if (this->set
->non_zero2
)
1243 s_sign
= 1 << (s_bits
- 1);
1244 s_mask
= ((1 << (32 - s_bits
)) - 1) << s_bits
;
1246 case PRIV_KEY_PUBLIC
:
1247 if (!bliss_public_key_from_asn1(object
, this->set
, &this->A
))
1252 case PRIV_KEY_SECRET1
:
1253 if (object
.len
!= 1 + (s_bits
* this->set
->n
+ 7)/8)
1257 this->s1
= malloc(this->set
->n
);
1259 /* Skip unused bits octet */
1260 object
= chunk_skip(object
, 1);
1261 packer
= bliss_bitpacker_create_from_data(object
);
1262 for (i
= 0; i
< this->set
->n
; i
++)
1264 packer
->read_bits(packer
, &value
, s_bits
);
1265 s
= (value
& s_sign
) ? value
| s_mask
: value
;
1266 if (s
< s_min
|| s
> s_max
)
1268 packer
->destroy(packer
);
1273 packer
->destroy(packer
);
1275 case PRIV_KEY_SECRET2
:
1276 if (object
.len
!= 1 + (s_bits
* this->set
->n
+ 7)/8)
1280 this->s2
= malloc(this->set
->n
);
1282 /* Skip unused bits octet */
1283 object
= chunk_skip(object
, 1);
1284 packer
= bliss_bitpacker_create_from_data(object
);
1285 for (i
= 0; i
< this->set
->n
; i
++)
1287 packer
->read_bits(packer
, &value
, s_bits
);
1288 s
= (value
& s_sign
) ? value
| s_mask
: value
;
1289 if (s
< s_min
|| s
> s_max
)
1291 packer
->destroy(packer
);
1294 this->s2
[i
] = 2 * s
;
1300 packer
->destroy(packer
);
1304 success
= parser
->success(parser
);
1307 parser
->destroy(parser
);
1314 return &this->public;