.oid = OID_BLISS_I,
.strength = 128,
.q = 12289,
+ .q_bits = 14,
.q2_inv = 6145,
.n = 512,
.n_bits = 9,
.oid = OID_BLISS_III,
.strength = 160,
.q = 12289,
+ .q_bits = 14,
.q2_inv = 6145,
.n = 512,
.n_bits = 9,
.oid = OID_BLISS_IV,
.strength = 192,
.q = 12289,
+ .q_bits = 14,
.q2_inv = 6145,
.n = 512,
.n_bits = 9,
*/
uint16_t q;
+ /**
+ * Number of bits in q
+ */
+ uint16_t q_bits;
+
/**
* Inverse of (q + 2) mod 2q
*/
public_key_t *public;
chunk_t pubkey;
- pubkey = bliss_public_key_info_encode(this->set->oid, this->A, this->set->n);
+ pubkey = bliss_public_key_info_encode(this->set->oid, this->A, this->set);
public = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_BLISS,
BUILD_BLOB_ASN1_DER, pubkey, BUILD_END);
free(pubkey.ptr);
chunk_t s1_chunk, s2_chunk, pubkey;
bool success = TRUE;
- pubkey = bliss_public_key_encode(this->A, this->set->n);
+ pubkey = bliss_public_key_encode(this->A, this->set);
/* Build private key as two polynomials with 8 bit coefficients */
s1_chunk = chunk_create(this->s1, this->set->n);
*encoding = asn1_wrap(ASN1_SEQUENCE, "mmss",
asn1_build_known_oid(this->set->oid),
- pubkey,
+ asn1_bitstring("m", pubkey),
asn1_simple_object(ASN1_OCTET_STRING, s1_chunk),
asn1_simple_object(ASN1_OCTET_STRING, s2_chunk)
);
return TRUE;
}
success = bliss_public_key_fingerprint(this->set->oid, this->A,
- this->set->n, type, fp);
+ this->set, type, fp);
lib->encoding->cache(lib->encoding, type, this, *fp);
return success;
static const asn1Object_t privkeyObjects[] = {
{ 0, "BLISSPrivateKey", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
{ 1, "keyType", ASN1_OID, ASN1_BODY }, /* 1 */
- { 1, "public", ASN1_OCTET_STRING, ASN1_BODY }, /* 2 */
+ { 1, "public", ASN1_BIT_STRING, ASN1_BODY }, /* 2 */
{ 1, "secret1", ASN1_OCTET_STRING, ASN1_BODY }, /* 3 */
{ 1, "secret2", ASN1_OCTET_STRING, ASN1_BODY }, /* 4 */
{ 0, "exit", ASN1_EOC, ASN1_EXIT }
}
break;
case PRIV_KEY_PUBLIC:
- if (object.len != 2*this->set->n)
+ if (!bliss_public_key_from_asn1(object, this->set, &this->A))
{
goto end;
}
- this->A = bliss_public_key_from_asn1(object, this->set->n);
break;
case PRIV_KEY_SECRET1:
if (object.len != this->set->n)
*/
#include "bliss_public_key.h"
-#include "bliss_param_set.h"
#include "bliss_signature.h"
+#include "bliss_bitpacker.h"
#include "bliss_fft.h"
#include "bliss_utils.h"
{
bool success = TRUE;
- *encoding = bliss_public_key_info_encode(this->set->oid, this->A, this->set->n);
+ *encoding = bliss_public_key_info_encode(this->set->oid, this->A, this->set);
if (type != PUBKEY_SPKI_ASN1_DER)
{
return TRUE;
}
success = bliss_public_key_fingerprint(this->set->oid, this->A,
- this->set->n, type, fp);
+ this->set, type, fp);
lib->encoding->cache(lib->encoding, type, this, *fp);
return success;
break;
}
case BLISS_SUBJECT_PUBLIC_KEY:
- if (object.len > 0 && *object.ptr == 0x00)
- {
- /* skip initial bit string octet defining 0 unused bits */
- object = chunk_skip(object, 1);
- }
- if (!asn1_parse_simple_object(&object, ASN1_OCTET_STRING,
- parser->get_level(parser)+1, "blissPublicKey"))
+ if (!bliss_public_key_from_asn1(object, this->set, &this->A))
{
goto end;
}
- if (object.len != 2*this->set->n)
- {
- goto end;
- }
- this->A = bliss_public_key_from_asn1(object, this->set->n);
break;
}
}
/**
* See header.
*/
-uint32_t* bliss_public_key_from_asn1(chunk_t object, int n)
+bool bliss_public_key_from_asn1(chunk_t object, bliss_param_set_t *set,
+ uint32_t **pubkey)
{
- uint32_t *pubkey;
- uint16_t coeff;
- u_char *pos;
+ bliss_bitpacker_t *packer;
+ uint16_t coefficient;
int i;
- pubkey = malloc(n * sizeof(uint32_t));
- pos = object.ptr;
+ /* skip initial bit string octet defining unused bits */
+ object = chunk_skip(object, 1);
- for (i = 0; i < n; i++)
+ if (8 * object.len < set->n * set->q_bits)
{
- coeff = untoh16(pos);
- pubkey[i] = (uint32_t)coeff;
- pos += 2;
+ return FALSE;
}
+ *pubkey = malloc(set->n * sizeof(uint32_t));
- return pubkey;
+ packer = bliss_bitpacker_create_from_data(object);
+
+ for (i = 0; i < set->n; i++)
+ {
+ packer->read_bits(packer, &coefficient, set->q_bits);
+ (*pubkey)[i] = (uint32_t)coefficient;
+ }
+ packer->destroy(packer);
+
+ return TRUE;
}
/**
* See header.
*/
-chunk_t bliss_public_key_encode(uint32_t *pubkey, int n)
+chunk_t bliss_public_key_encode(uint32_t *pubkey, bliss_param_set_t *set)
{
- u_char *pos;
+ bliss_bitpacker_t *packer;
chunk_t encoding;
int i;
- pos = asn1_build_object(&encoding, ASN1_OCTET_STRING, 2 * n);
+ packer = bliss_bitpacker_create(set->n * set->q_bits);
- for (i = 0; i < n; i++)
+ for (i = 0; i < set->n; i++)
{
- htoun16(pos, (uint16_t)pubkey[i]);
- pos += 2;
+ packer->write_bits(packer, pubkey[i], set->q_bits);
}
+ encoding = packer->extract_buf(packer);
+ packer->destroy(packer);
return encoding;
}
/**
* See header.
*/
-chunk_t bliss_public_key_info_encode(int oid, uint32_t *pubkey, int n)
+chunk_t bliss_public_key_info_encode(int oid, uint32_t *pubkey,
+ bliss_param_set_t *set)
{
chunk_t encoding, pubkey_encoding;
- pubkey_encoding = bliss_public_key_encode(pubkey, n);
+ pubkey_encoding = bliss_public_key_encode(pubkey, set);
encoding = asn1_wrap(ASN1_SEQUENCE, "mm",
asn1_wrap(ASN1_SEQUENCE, "mm",
/**
* See header.
*/
-bool bliss_public_key_fingerprint(int oid, uint32_t *pubkey, int n,
+bool bliss_public_key_fingerprint(int oid, uint32_t *pubkey,
+ bliss_param_set_t *set,
cred_encoding_type_t type, chunk_t *fp)
{
hasher_t *hasher;
switch (type)
{
case KEYID_PUBKEY_SHA1:
- key = bliss_public_key_encode(pubkey, n);
+ key = bliss_public_key_encode(pubkey, set);
break;
case KEYID_PUBKEY_INFO_SHA1:
- key = bliss_public_key_info_encode(oid, pubkey, n);
+ key = bliss_public_key_info_encode(oid, pubkey, set);
break;
default:
return FALSE;
#ifndef BLISS_PUBLIC_KEY_H_
#define BLISS_PUBLIC_KEY_H_
+#include "bliss_param_set.h"
+
#include <credentials/builder.h>
#include <credentials/cred_encoding.h>
#include <credentials/keys/public_key.h>
/* The following functions are shared with the bliss_private_key class */
/**
- * Parse an ASN.1 OCTET STRING into an array of public key coefficients
+ * Parse an ASN.1 BIT STRING into an array of public key coefficients
*
- * @param object ASN.1 encoded subjectPublicKey
- * @param n number of public key coefficients
- * @result coefficients of public key vector
+ * @param data packed subjectPublicKey
+ * @param set BLISS parameter set for public key vector
+ * @param pubkey coefficients of public key vector
+ * @return TRUE if parsing successful
*/
-uint32_t* bliss_public_key_from_asn1(chunk_t object, int n);
+bool bliss_public_key_from_asn1(chunk_t object, bliss_param_set_t *set,
+ uint32_t **pubkey);
/**
* Encode a raw BLISS subjectPublicKey in ASN.1 DER format
*
* @param coefficients of public key vector
- * @param n number of public key coefficients
+ * @param set BLISS parameter set for the public key vector
* @result ASN.1 encoded subjectPublicKey
*/
-chunk_t bliss_public_key_encode(uint32_t *pubkey, int n);
+chunk_t bliss_public_key_encode(uint32_t *pubkey, bliss_param_set_t *set);
/**
* Encode a BLISS subjectPublicKeyInfo record in ASN.1 DER format
*
* @param oid BLISS public key type OID
* @param pubkey coefficients of public key vector
- * @param n number of public key coefficients
+ * @param n BLISS parameter set for the public key vector
* @result ASN.1 encoded subjectPublicKeyInfo record
*/
-chunk_t bliss_public_key_info_encode(int oid, uint32_t *pubkey, int n);
+chunk_t bliss_public_key_info_encode(int oid, uint32_t *pubkey,
+ bliss_param_set_t *set);
/**
* Generate a BLISS public key fingerprint
*
* @param oid BLISS public key type OID
* @param pubkey coefficients of public key vector
- * @param n number of public key coefficients
+ * @param n BLISS parameter set for the public key vector
* @param type type of fingerprint to be generated
* @param fp generated fingerprint (must be freed by caller)
* @result TRUE if generation was successful
*/
-bool bliss_public_key_fingerprint(int oid, uint32_t *pubkey, int n,
+bool bliss_public_key_fingerprint(int oid, uint32_t *pubkey,
+ bliss_param_set_t *set,
cred_encoding_type_t type, chunk_t *fp);
#endif /** BLISS_PUBLIC_KEY_H_ @}*/