Applied bit packing to BLISS public key

This commit is contained in:
Andreas Steffen
2014-11-29 14:51:18 +01:00
parent bf749fa1fb
commit 0d8a3f5d01
5 changed files with 68 additions and 55 deletions
@@ -123,6 +123,7 @@ static bliss_param_set_t bliss_param_sets[] = {
.oid = OID_BLISS_I, .oid = OID_BLISS_I,
.strength = 128, .strength = 128,
.q = 12289, .q = 12289,
.q_bits = 14,
.q2_inv = 6145, .q2_inv = 6145,
.n = 512, .n = 512,
.n_bits = 9, .n_bits = 9,
@@ -150,6 +151,7 @@ static bliss_param_set_t bliss_param_sets[] = {
.oid = OID_BLISS_III, .oid = OID_BLISS_III,
.strength = 160, .strength = 160,
.q = 12289, .q = 12289,
.q_bits = 14,
.q2_inv = 6145, .q2_inv = 6145,
.n = 512, .n = 512,
.n_bits = 9, .n_bits = 9,
@@ -177,6 +179,7 @@ static bliss_param_set_t bliss_param_sets[] = {
.oid = OID_BLISS_IV, .oid = OID_BLISS_IV,
.strength = 192, .strength = 192,
.q = 12289, .q = 12289,
.q_bits = 14,
.q2_inv = 6145, .q2_inv = 6145,
.n = 512, .n = 512,
.n_bits = 9, .n_bits = 9,
@@ -65,6 +65,11 @@ struct bliss_param_set_t {
*/ */
uint16_t q; uint16_t q;
/**
* Number of bits in q
*/
uint16_t q_bits;
/** /**
* Inverse of (q + 2) mod 2q * Inverse of (q + 2) mod 2q
*/ */
@@ -430,7 +430,7 @@ METHOD(private_key_t, get_public_key, public_key_t*,
public_key_t *public; public_key_t *public;
chunk_t pubkey; 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, public = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_BLISS,
BUILD_BLOB_ASN1_DER, pubkey, BUILD_END); BUILD_BLOB_ASN1_DER, pubkey, BUILD_END);
free(pubkey.ptr); free(pubkey.ptr);
@@ -450,7 +450,7 @@ METHOD(private_key_t, get_encoding, bool,
chunk_t s1_chunk, s2_chunk, pubkey; chunk_t s1_chunk, s2_chunk, pubkey;
bool success = TRUE; 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 */ /* Build private key as two polynomials with 8 bit coefficients */
s1_chunk = chunk_create(this->s1, this->set->n); s1_chunk = chunk_create(this->s1, this->set->n);
@@ -458,7 +458,7 @@ METHOD(private_key_t, get_encoding, bool,
*encoding = asn1_wrap(ASN1_SEQUENCE, "mmss", *encoding = asn1_wrap(ASN1_SEQUENCE, "mmss",
asn1_build_known_oid(this->set->oid), 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, s1_chunk),
asn1_simple_object(ASN1_OCTET_STRING, s2_chunk) asn1_simple_object(ASN1_OCTET_STRING, s2_chunk)
); );
@@ -488,7 +488,7 @@ METHOD(private_key_t, get_fingerprint, bool,
return TRUE; return TRUE;
} }
success = bliss_public_key_fingerprint(this->set->oid, this->A, 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); lib->encoding->cache(lib->encoding, type, this, *fp);
return success; return success;
@@ -950,7 +950,7 @@ bliss_private_key_t *bliss_private_key_gen(key_type_t type, va_list args)
static const asn1Object_t privkeyObjects[] = { static const asn1Object_t privkeyObjects[] = {
{ 0, "BLISSPrivateKey", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */ { 0, "BLISSPrivateKey", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
{ 1, "keyType", ASN1_OID, ASN1_BODY }, /* 1 */ { 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, "secret1", ASN1_OCTET_STRING, ASN1_BODY }, /* 3 */
{ 1, "secret2", ASN1_OCTET_STRING, ASN1_BODY }, /* 4 */ { 1, "secret2", ASN1_OCTET_STRING, ASN1_BODY }, /* 4 */
{ 0, "exit", ASN1_EOC, ASN1_EXIT } { 0, "exit", ASN1_EOC, ASN1_EXIT }
@@ -1012,11 +1012,10 @@ bliss_private_key_t *bliss_private_key_load(key_type_t type, va_list args)
} }
break; break;
case PRIV_KEY_PUBLIC: case PRIV_KEY_PUBLIC:
if (object.len != 2*this->set->n) if (!bliss_public_key_from_asn1(object, this->set, &this->A))
{ {
goto end; goto end;
} }
this->A = bliss_public_key_from_asn1(object, this->set->n);
break; break;
case PRIV_KEY_SECRET1: case PRIV_KEY_SECRET1:
if (object.len != this->set->n) if (object.len != this->set->n)
@@ -14,8 +14,8 @@
*/ */
#include "bliss_public_key.h" #include "bliss_public_key.h"
#include "bliss_param_set.h"
#include "bliss_signature.h" #include "bliss_signature.h"
#include "bliss_bitpacker.h"
#include "bliss_fft.h" #include "bliss_fft.h"
#include "bliss_utils.h" #include "bliss_utils.h"
@@ -220,7 +220,7 @@ METHOD(public_key_t, get_encoding, bool,
{ {
bool success = TRUE; 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) if (type != PUBKEY_SPKI_ASN1_DER)
{ {
@@ -244,7 +244,7 @@ METHOD(public_key_t, get_fingerprint, bool,
return TRUE; return TRUE;
} }
success = bliss_public_key_fingerprint(this->set->oid, this->A, 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); lib->encoding->cache(lib->encoding, type, this, *fp);
return success; return success;
@@ -361,21 +361,10 @@ bliss_public_key_t *bliss_public_key_load(key_type_t type, va_list args)
break; break;
} }
case BLISS_SUBJECT_PUBLIC_KEY: case BLISS_SUBJECT_PUBLIC_KEY:
if (object.len > 0 && *object.ptr == 0x00) if (!bliss_public_key_from_asn1(object, this->set, &this->A))
{
/* 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"))
{ {
goto end; goto end;
} }
if (object.len != 2*this->set->n)
{
goto end;
}
this->A = bliss_public_key_from_asn1(object, this->set->n);
break; break;
} }
} }
@@ -395,42 +384,51 @@ end:
/** /**
* See header. * 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; bliss_bitpacker_t *packer;
uint16_t coeff; uint16_t coefficient;
u_char *pos;
int i; int i;
pubkey = malloc(n * sizeof(uint32_t)); /* skip initial bit string octet defining unused bits */
pos = object.ptr; object = chunk_skip(object, 1);
for (i = 0; i < n; i++) if (8 * object.len < set->n * set->q_bits)
{ {
coeff = untoh16(pos); return FALSE;
pubkey[i] = (uint32_t)coeff;
pos += 2;
} }
*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. * 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; chunk_t encoding;
int i; 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]); packer->write_bits(packer, pubkey[i], set->q_bits);
pos += 2;
} }
encoding = packer->extract_buf(packer);
packer->destroy(packer);
return encoding; return encoding;
} }
@@ -438,11 +436,12 @@ chunk_t bliss_public_key_encode(uint32_t *pubkey, int n)
/** /**
* See header. * 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; 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", encoding = asn1_wrap(ASN1_SEQUENCE, "mm",
asn1_wrap(ASN1_SEQUENCE, "mm", asn1_wrap(ASN1_SEQUENCE, "mm",
@@ -456,7 +455,8 @@ chunk_t bliss_public_key_info_encode(int oid, uint32_t *pubkey, int n)
/** /**
* See header. * 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) cred_encoding_type_t type, chunk_t *fp)
{ {
hasher_t *hasher; hasher_t *hasher;
@@ -465,10 +465,10 @@ bool bliss_public_key_fingerprint(int oid, uint32_t *pubkey, int n,
switch (type) switch (type)
{ {
case KEYID_PUBKEY_SHA1: case KEYID_PUBKEY_SHA1:
key = bliss_public_key_encode(pubkey, n); key = bliss_public_key_encode(pubkey, set);
break; break;
case KEYID_PUBKEY_INFO_SHA1: case KEYID_PUBKEY_INFO_SHA1:
key = bliss_public_key_info_encode(oid, pubkey, n); key = bliss_public_key_info_encode(oid, pubkey, set);
break; break;
default: default:
return FALSE; return FALSE;
@@ -21,6 +21,8 @@
#ifndef BLISS_PUBLIC_KEY_H_ #ifndef BLISS_PUBLIC_KEY_H_
#define BLISS_PUBLIC_KEY_H_ #define BLISS_PUBLIC_KEY_H_
#include "bliss_param_set.h"
#include <credentials/builder.h> #include <credentials/builder.h>
#include <credentials/cred_encoding.h> #include <credentials/cred_encoding.h>
#include <credentials/keys/public_key.h> #include <credentials/keys/public_key.h>
@@ -52,44 +54,48 @@ bliss_public_key_t *bliss_public_key_load(key_type_t type, va_list args);
/* The following functions are shared with the bliss_private_key class */ /* 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 data packed subjectPublicKey
* @param n number of public key coefficients * @param set BLISS parameter set for public key vector
* @result coefficients of 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 * Encode a raw BLISS subjectPublicKey in ASN.1 DER format
* *
* @param coefficients of public key vector * @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 * @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 * Encode a BLISS subjectPublicKeyInfo record in ASN.1 DER format
* *
* @param oid BLISS public key type OID * @param oid BLISS public key type OID
* @param pubkey coefficients of public key vector * @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 * @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 * Generate a BLISS public key fingerprint
* *
* @param oid BLISS public key type OID * @param oid BLISS public key type OID
* @param pubkey coefficients of public key vector * @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 type type of fingerprint to be generated
* @param fp generated fingerprint (must be freed by caller) * @param fp generated fingerprint (must be freed by caller)
* @result TRUE if generation was successful * @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); cred_encoding_type_t type, chunk_t *fp);
#endif /** BLISS_PUBLIC_KEY_H_ @}*/ #endif /** BLISS_PUBLIC_KEY_H_ @}*/