/*! * Hash a null-terminated string to a byte array. * * @param input_buf The input buffer. * @param input_len The input buffer length (in bytes). * @param output_buf A pre-allocated output buffer of size hash_len. * @param hash_len Length of the output hash (in bytes). Should be approximately bit size of curve group order. * @param hash_prefix prefix for hash function. */ status_t hash_buffer_to_bytes(uint8_t *input_buf, int input_len, uint8_t *output_buf, int hash_len, uint8_t hash_prefix) { LEAVE_IF(input_buf == NULL || output_buf == NULL, "uninitialized argument."); int i, new_input_len = input_len + 2; // extra byte for prefix uint8_t first_block = 0; uint8_t new_input[new_input_len+1]; // printf("orig input => \n"); // print_as_hex(input_buf, input_len); memset(new_input, 0, new_input_len+1); new_input[0] = first_block; // block number (always 0 by default) new_input[1] = hash_prefix; // set hash prefix memcpy((uint8_t *)(new_input+2), input_buf, input_len); // copy input bytes // printf("new input => \n"); // print_as_hex(new_input, new_input_len); // prepare output buf memset(output_buf, 0, hash_len); if (hash_len <= SHA_LEN) { uint8_t md[SHA_LEN+1]; SHA_FUNC(md, new_input, new_input_len); memcpy(output_buf, md, hash_len); } else { // apply variable-size hash technique to get desired size // determine block count. int blocks = (int) ceil(((double) hash_len) / SHA_LEN); //debug("Num blocks needed: %d\n", blocks); uint8_t md[SHA_LEN+1]; uint8_t md2[(blocks * SHA_LEN)+1]; uint8_t *target_buf = md2; for(i = 0; i < blocks; i++) { /* compute digest = SHA-2( i || prefix || input_buf ) || ... || SHA-2( n-1 || prefix || input_buf ) */ target_buf += (i * SHA_LEN); new_input[0] = (uint8_t) i; //debug("input %d => ", i); //print_as_hex(new_input, new_input_len); SHA_FUNC(md, new_input, new_input_len); memcpy(target_buf, md, hash_len); //debug("block %d => ", i); //print_as_hex(md, SHA_LEN); memset(md, 0, SHA_LEN); } // copy back to caller memcpy(output_buf, md2, hash_len); } return ELEMENT_OK; }
status_t element_to_key(element_t e, uint8_t *data, int data_len, uint8_t label) { LEAVE_IF(e->isInitialized != TRUE, "uninitialized argument."); // adds an extra null byte by default - will use this last byte for the label int d_len = element_length(e), digest_len = SHA_LEN; uint8_t d[d_len + 1]; memset(d, 0, d_len); // write e to a tmp buf if(d_len > 0 && digest_len <= data_len) { element_to_bytes(d, d_len, e); d[d_len-1] = label; #ifdef DEBUG printf("%s: bytes form....\n", __FUNCTION__); print_as_hex(d, d_len); #endif // hash buf using md_map_sh256 and store data_len bytes in data uint8_t digest[digest_len + 1]; memset(digest, 0, digest_len); SHA_FUNC(digest, d, d_len); memcpy(data, digest, digest_len); #ifdef DEBUG printf("%s: digest: ", __FUNCTION__); print_as_hex(data, digest_len); #endif return ELEMENT_OK; } return ELEMENT_INVALID_ARG; }
status_t element_from_hash(element_t e, unsigned char *data, int len) { LEAVE_IF(e->isInitialized == FALSE, "uninitialized argument."); GroupType type = e->type; status_t result = ELEMENT_OK; int digest_len = SHA_LEN; unsigned char digest[digest_len + 1]; memset(digest, 0, digest_len); SHA_FUNC(digest, data, len); #ifdef DEBUG printf("%s: digest: ", __FUNCTION__); print_as_hex(digest, digest_len); #endif switch(type) { case ZR: bn_read_bin(e->bn, digest, digest_len); if(bn_cmp(e->bn, e->order) == CMP_GT) bn_mod(e->bn, e->bn, e->order); // bn_print(e->bn); break; case G1: g1_map(e->g1, digest, digest_len); break; case G2: g2_map(e->g2, digest, digest_len); break; default: result = ELEMENT_INVALID_TYPES; break; } return result; }
status_t hash_buffer_to_bytes(uint8_t *input, int input_len, uint8_t *output, int output_len, uint8_t label) { LEAVE_IF(input == NULL || output == NULL, "uninitialized argument."); // adds an extra null byte by default - will use this last byte for the label int digest_len = SHA_LEN; if(digest_len <= output_len) { // hash buf using md_map_sh256 and store data_len bytes in data uint8_t digest[digest_len + 1]; memset(digest, 0, digest_len); SHA_FUNC(digest, input, input_len); memcpy(output, digest, digest_len); #ifdef DEBUG printf("%s: digest: ", __FUNCTION__); print_as_hex(output, digest_len); #endif return ELEMENT_OK; } return ELEMENT_INVALID_ARG; }
status_t element_from_hash(element_t e, unsigned char *data, int len) { LEAVE_IF(e->isInitialized == FALSE, "uninitialized argument."); GroupType type = e->type; status_t result = ELEMENT_OK; int digest_len = SHA_LEN; unsigned char digest[digest_len + 1]; memset(digest, 0, digest_len); SHA_FUNC(digest, data, len); switch(type) { case ZR: bn_read_bin(e->bn, digest, digest_len); break; case G1: g1_map(e->g1, digest, digest_len); break; case G2: g2_map(e->g2, digest, digest_len); break; default: result = ELEMENT_INVALID_TYPES; break; } return result; }