Skip to content

Commit

Permalink
Add serialize and deserialize to XMSS
Browse files Browse the repository at this point in the history
  • Loading branch information
ducnguyen-sb committed Sep 7, 2023
1 parent ec3d3e0 commit 2a7da01
Show file tree
Hide file tree
Showing 37 changed files with 261 additions and 88 deletions.
9 changes: 4 additions & 5 deletions src/sig_stfl/lms/sig_stfl_lms.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
#include "sig_stfl_lms_wrap.h"
#include "sig_stfl_lms.h"


// ======================== LMS-SHA256 H5/W1 ======================== //

OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h5_w1_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key) {
Expand Down Expand Up @@ -104,11 +103,11 @@ void OQS_SECRET_KEY_LMS_free(OQS_SIG_STFL_SECRET_KEY *sk) {
}

/* Convert LMS secret key object to byte string */
size_t OQS_SECRET_KEY_LMS_serialize_key(const OQS_SIG_STFL_SECRET_KEY *sk, uint8_t **sk_buf) {
return oqs_serialize_lms_key(sk, sk_buf);
OQS_STATUS OQS_SECRET_KEY_LMS_serialize_key(const OQS_SIG_STFL_SECRET_KEY *sk, size_t *sk_len, uint8_t **sk_buf_ptr) {
return oqs_serialize_lms_key(sk, sk_len, sk_buf_ptr);
}

/* Insert lms byte string in an LMS secret key object */
OQS_STATUS OQS_SECRET_KEY_LMS_deserialize_key(OQS_SIG_STFL_SECRET_KEY *sk, size_t key_len, const uint8_t *sk_buf) {
return oqs_deserialize_lms_key(sk, key_len, sk_buf);
OQS_STATUS OQS_SECRET_KEY_LMS_deserialize_key(OQS_SIG_STFL_SECRET_KEY *sk, const size_t sk_len, const uint8_t *sk_buf) {
return oqs_deserialize_lms_key(sk, sk_len, sk_buf);
}
8 changes: 4 additions & 4 deletions src/sig_stfl/lms/sig_stfl_lms.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h5_w1_keypair(uint8_t *public_key
OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H5_W1_new(void);

/* Convert LMS secret key object to byte string */
size_t OQS_SECRET_KEY_LMS_serialize_key(const OQS_SIG_STFL_SECRET_KEY *sk, uint8_t **sk_buf);
OQS_STATUS OQS_SECRET_KEY_LMS_serialize_key(const OQS_SIG_STFL_SECRET_KEY *sk, size_t *sk_len, uint8_t **sk_buf_ptr);

/* Insert lms byte string in an LMS secret key object */
OQS_STATUS OQS_SECRET_KEY_LMS_deserialize_key(OQS_SIG_STFL_SECRET_KEY *sk, size_t key_len, const uint8_t *sk_buf);
OQS_STATUS OQS_SECRET_KEY_LMS_deserialize_key(OQS_SIG_STFL_SECRET_KEY *sk, const size_t key_len, const uint8_t *sk_buf);

OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h5_w1_new(void);

Expand All @@ -38,8 +38,8 @@ int oqs_sig_stfl_lms_verify(const uint8_t *m, size_t mlen, const uint8_t *sm, si

void oqs_secret_lms_key_free(OQS_SIG_STFL_SECRET_KEY *sk);

size_t oqs_serialize_lms_key(const OQS_SIG_STFL_SECRET_KEY *sk, uint8_t **sk_key);
int oqs_deserialize_lms_key(OQS_SIG_STFL_SECRET_KEY *sk, size_t key_len, const uint8_t *sk_buf);
OQS_STATUS oqs_serialize_lms_key(const OQS_SIG_STFL_SECRET_KEY *sk, size_t *sk_len, uint8_t **sk_key);
OQS_STATUS oqs_deserialize_lms_key(OQS_SIG_STFL_SECRET_KEY *sk, const size_t sk_len, const uint8_t *sk_buf);

// ---------------------------- FUNCTIONS INDEPENDENT OF VARIANT -----------------------------------------

Expand Down
152 changes: 80 additions & 72 deletions src/sig_stfl/lms/sig_stfl_lms_functions.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: MIT

#include <string.h>
#include <oqs/oqs.h>
#include "sig_stfl_lms.h"
#include "external/config.h"
#include "external/hss_verify_inc.h"
Expand Down Expand Up @@ -378,71 +379,72 @@ void oqs_secret_lms_key_free(OQS_SIG_STFL_SECRET_KEY *sk) {
* Convert LMS secret key object to byte string
* Writes secret key + aux data if present
*/
size_t oqs_serialize_lms_key(const OQS_SIG_STFL_SECRET_KEY *sk, uint8_t **sk_key) {
OQS_STATUS oqs_serialize_lms_key(const OQS_SIG_STFL_SECRET_KEY *sk, size_t *sk_len, uint8_t **sk_key) {

oqs_lms_key_data *lms_key_data = NULL;
size_t key_len = 0;
if (sk) {
uint8_t *sk_key_buf = NULL;
lms_key_data = sk->secret_key_data;
if (lms_key_data && lms_key_data->sec_key) {
size_t buf_size_needed = lms_key_data->len_aux_data + lms_key_data->len_sec_key;
key_len = buf_size_needed;
/* pass back serialized data */
if (sk_key) {
if (buf_size_needed) {
sk_key_buf = malloc(buf_size_needed * sizeof(uint8_t));
if (sk_key_buf) {

/*
* Serialized data is sec_key followed by aux data
* So aux data begins after buffer top + sec_key length
*/
if (lms_key_data->len_sec_key) {
memcpy(sk_key_buf, lms_key_data->sec_key, lms_key_data->len_sec_key);
}

if (lms_key_data->len_aux_data) {
memcpy(sk_key_buf + lms_key_data->len_sec_key, lms_key_data->aux_data, lms_key_data->len_aux_data);
}

*sk_key = sk_key_buf;
key_len = sk->length_secret_key + lms_key_data->len_aux_data;
}
}
} //sk_key
}
} //sk
return key_len;
if (sk == NULL || sk_len == NULL || sk_key == NULL) {
return OQS_ERROR;
}

oqs_lms_key_data *lms_key_data = sk->secret_key_data;

if (lms_key_data == NULL || lms_key_data->sec_key == NULL) {
return OQS_ERROR;
}

size_t key_len = lms_key_data->len_aux_data + lms_key_data->len_sec_key;

if (key_len == 0) {
return OQS_ERROR;
}

uint8_t *sk_key_buf = malloc(key_len * sizeof(uint8_t));

if (sk_key_buf == NULL) {
return OQS_ERROR;
}
/* pass back serialized data */
/*
* Serialized data is sec_key followed by aux data
* So aux data begins after buffer top + sec_key length
*/
if (lms_key_data->len_sec_key != 0) {
memcpy(sk_key_buf, lms_key_data->sec_key, lms_key_data->len_sec_key);
}

if (lms_key_data->len_aux_data != 0) {
memcpy(sk_key_buf + lms_key_data->len_sec_key, lms_key_data->aux_data, lms_key_data->len_aux_data);
}

*sk_key = sk_key_buf;
*sk_len = sk->length_secret_key + lms_key_data->len_aux_data;

return OQS_SUCCESS;
}

/*
* Convert LMS byte string to secret key object
* Writes secret key + aux data if present
* key_len is priv key length + aux length
*/
int oqs_deserialize_lms_key(OQS_SIG_STFL_SECRET_KEY *sk, size_t key_len, const uint8_t *sk_buf) {
int oqs_status = -1;
OQS_STATUS oqs_deserialize_lms_key(OQS_SIG_STFL_SECRET_KEY *sk, const size_t sk_len, const uint8_t *sk_buf) {

oqs_lms_key_data *lms_key_data = NULL;
uint8_t priv_ky_len = hss_get_private_key_len((unsigned )(1), NULL, NULL);
uint8_t *lms_sk = NULL;
uint8_t *lms_aux = NULL;
uint8_t lms_sk_len = hss_get_private_key_len((unsigned )(1), NULL, NULL);

if ((!sk) || (key_len == 0) || (key_len < priv_ky_len) || (!sk_buf)) {
return oqs_status;
if (sk == NULL || sk_buf == NULL || (sk_len == 0) || (sk_len < lms_sk_len )) {
return OQS_ERROR;
}

if (sk->secret_key_data) {
if (sk->secret_key_data != NULL) {
//Key data already present
//We dont want to trample over data
return oqs_status;
return OQS_ERROR;
}

uint8_t *lms_sk = NULL;
uint8_t *lms_aux = NULL;

unsigned levels = 0;

int key_buf_left = key_len - priv_ky_len;

param_set_t lm_type[ MAX_HSS_LEVELS ];
param_set_t lm_ots_type[ MAX_HSS_LEVELS ];

Expand All @@ -452,36 +454,42 @@ int oqs_deserialize_lms_key(OQS_SIG_STFL_SECRET_KEY *sk, size_t key_len, const u
lm_ots_type,
NULL,
(void *)sk_buf)) {
return oqs_status;
return OQS_ERROR;
}

lms_key_data = malloc(sizeof(oqs_lms_key_data));
if (lms_key_data) {
lms_sk = malloc(priv_ky_len * sizeof(uint8_t));
if (lms_sk) {
memcpy(lms_sk, sk_buf, priv_ky_len);
lms_key_data->sec_key = lms_sk;
lms_key_data->len_sec_key = priv_ky_len;
} else {
OQS_MEM_insecure_free(lms_key_data);
return oqs_status;
}
lms_sk = malloc(lms_sk_len * sizeof(uint8_t));

if (key_buf_left) {
lms_aux = malloc(key_buf_left * sizeof(uint8_t));
if (lms_aux) {
memcpy(lms_aux, (sk_buf + priv_ky_len), key_buf_left);
lms_key_data->aux_data = lms_aux;
lms_key_data->len_aux_data = key_buf_left;
} else {
OQS_MEM_insecure_free(lms_key_data);
OQS_MEM_insecure_free(lms_sk);
return oqs_status;
}
if (lms_key_data == NULL || lms_sk == NULL) {
goto err;
}

memcpy(lms_sk, sk_buf, lms_sk_len);
lms_key_data->sec_key = lms_sk;
lms_key_data->len_sec_key = lms_sk_len;

int key_buf_left = sk_len - lms_sk_len;
if (key_buf_left) {
lms_aux = malloc(key_buf_left * sizeof(uint8_t));

if (lms_aux == NULL) {
goto err;
}

sk->secret_key_data = lms_key_data;
oqs_status = 0;
memcpy(lms_aux, sk_buf + lms_sk_len, key_buf_left);
lms_key_data->aux_data = lms_aux;
lms_key_data->len_aux_data = key_buf_left;
}
return oqs_status;

sk->secret_key_data = lms_key_data;
goto success;

err:
OQS_MEM_insecure_free(lms_key_data);
OQS_MEM_insecure_free(lms_sk);
OQS_MEM_insecure_free(lms_aux);
return OQS_ERROR;

success:
return OQS_SUCCESS;
}
14 changes: 7 additions & 7 deletions src/sig_stfl/sig_stfl.h
Original file line number Diff line number Diff line change
Expand Up @@ -206,23 +206,23 @@ typedef struct OQS_SIG_STFL_SECRET_KEY {
* Secret Key retrieval Function
*
* @param[in] sk The secret key represented as OQS_SIG_STFL_SECRET_KEY object
* @param[out] sk_buf private key data as a byte stream
* @param[out] sk_len length of private key as a byte stream
* @param[out] sk_buf_ptr pointer to private key data as a byte stream
* @returns length of key material data available
* Caller deletes the buffer if memory was allocated.
*/
size_t (*serialize_key)(const OQS_SIG_STFL_SECRET_KEY *sk, uint8_t **sk_buf);
OQS_STATUS (*serialize_key)(const OQS_SIG_STFL_SECRET_KEY *sk, size_t *sk_len, uint8_t **sk_buf_ptr);

/**
* set Secret Key to internal structure Function
*
* @param[in] sk OQS_SIG_STFL_SECRET_KEY object
* @param[in] key_len length of the returned byte string
* @param[in] sk_key The secret key represented as OQS_SIG_STFL_SECRET_KEY object
* @param[in] key_len length of the returned byte string
* @param[out] sk OQS_SIG_STFL_SECRET_KEY object
* @param[in] sk_len length of the returned byte string
* @param[in] sk_buf The secret key represented as OQS_SIG_STFL_SECRET_KEY object
* @returns status of the operation populated with key material none-zero length. Caller
* deletes the buffer. if sk_buf is NULL the function returns the length
*/
OQS_STATUS (*deserialize_key)(OQS_SIG_STFL_SECRET_KEY *sk, size_t key_len, const uint8_t *sk_buf);
OQS_STATUS (*deserialize_key)(OQS_SIG_STFL_SECRET_KEY *sk, const size_t sk_len, const uint8_t *sk_buf);

/**
* Secret Key Locking Function
Expand Down
1 change: 1 addition & 0 deletions src/sig_stfl/xmss/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ set(SRCS external/core_hash.c
external/xmss.c
external/xmss_commons.c
external/xmss_core_fast.c
sig_stfl_xmss_secret_key_functions.c
)

if (OQS_ENABLE_SIG_STFL_xmss_sha256_h10)
Expand Down
2 changes: 2 additions & 0 deletions src/sig_stfl/xmss/external/sign.c
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// TODO: remove

/*=============================================================================
* Copyright (c) 2022 by SandboxAQ Inc
* Author: Duc Tri Nguyen ([email protected])
Expand Down
2 changes: 2 additions & 0 deletions src/sig_stfl/xmss/external/sign_params.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// TODO: remove

#ifndef NIST_PARAM_H
#define NIST_PARAM_H

Expand Down
9 changes: 9 additions & 0 deletions src/sig_stfl/xmss/sig_stfl_xmss.h
Original file line number Diff line number Diff line change
Expand Up @@ -494,4 +494,13 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_sigs_total(unsigned l

#endif

/*
* Secret key functions
*/
/* Serialize XMSS secret key data into a byte string */
OQS_STATUS OQS_SECRET_KEY_XMSS_serialize_key(const OQS_SIG_STFL_SECRET_KEY *sk, size_t *sk_len, uint8_t **sk_buf_ptr);

/* Deserialize XMSS byte string into an XMSS secret key data */
OQS_STATUS OQS_SECRET_KEY_XMSS_deserialize_key(OQS_SIG_STFL_SECRET_KEY *sk, const size_t sk_len, const uint8_t *sk_buf);

#endif /* OQS_SIG_STFL_XMSS_H */
40 changes: 40 additions & 0 deletions src/sig_stfl/xmss/sig_stfl_xmss_secret_key_functions.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#include <oqs/oqs.h>
#include <string.h>
#include "sig_stfl_xmss.h"

/* Serialize XMSS secret key data into a byte string */
OQS_STATUS OQS_SECRET_KEY_XMSS_serialize_key(const OQS_SIG_STFL_SECRET_KEY *sk, size_t *sk_len, uint8_t **sk_buf_ptr) {
if (sk == NULL || sk_len == NULL || sk_buf_ptr == NULL) {
return OQS_ERROR;
}

uint8_t *sk_buf = malloc(sk->length_secret_key * sizeof(uint8_t));
if (sk_buf == NULL) {
return OQS_ERROR;
}

// Simply copy byte string of secret_key_data
memcpy(sk_buf, sk->secret_key_data, sk->length_secret_key);

*sk_buf_ptr = sk_buf;
*sk_len = sk->length_secret_key;

return OQS_SUCCESS;
}

/* Deserialize XMSS byte string into an XMSS secret key data */
OQS_STATUS OQS_SECRET_KEY_XMSS_deserialize_key(OQS_SIG_STFL_SECRET_KEY *sk, const size_t sk_len, const uint8_t *sk_buf) {
if (sk == NULL || sk_buf == NULL || (sk_len == 0) || (sk_len != sk->length_secret_key)) {
return OQS_ERROR;
}

if (sk->secret_key_data != NULL) {
// Secret key data already present
// We don't want to trample over exist data
return OQS_ERROR;
}

memcpy(sk->secret_key_data, sk_buf, sk_len);

return OQS_SUCCESS;
}
4 changes: 4 additions & 0 deletions src/sig_stfl/xmss/sig_stfl_xmss_sha256_h10.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHA256_H10_new(void) {
sk->sigs_left = NULL;
sk->sigs_total = NULL;

// Secret serialize/deserialize function
sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key;
sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key;

// Initialize the key with length_secret_key amount of bytes.
sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t));
memset(sk->secret_key_data, 0, sk->length_secret_key);
Expand Down
4 changes: 4 additions & 0 deletions src/sig_stfl/xmss/sig_stfl_xmss_sha256_h16.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHA256_H16_new(void) {
sk->sigs_left = NULL;
sk->sigs_total = NULL;

// Secret serialize/deserialize function
sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key;
sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key;

// Initialize the key with length_secret_key amount of bytes.
sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t));
memset(sk->secret_key_data, 0, sk->length_secret_key);
Expand Down
4 changes: 4 additions & 0 deletions src/sig_stfl/xmss/sig_stfl_xmss_sha256_h20.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHA256_H20_new(void) {
sk->sigs_left = NULL;
sk->sigs_total = NULL;

// Secret serialize/deserialize function
sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key;
sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key;

// Initialize the key with length_secret_key amount of bytes.
sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t));
memset(sk->secret_key_data, 0, sk->length_secret_key);
Expand Down
4 changes: 4 additions & 0 deletions src/sig_stfl/xmss/sig_stfl_xmss_sha512_h10.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHA512_H10_new(void) {
sk->sigs_left = NULL;
sk->sigs_total = NULL;

// Secret serialize/deserialize function
sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key;
sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key;

// Initialize the key with length_secret_key amount of bytes.
sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t));
memset(sk->secret_key_data, 0, sk->length_secret_key);
Expand Down
Loading

0 comments on commit 2a7da01

Please sign in to comment.