lopy4/components/hash-sigs-master/hss_compute.c
/*
 * Compute the value of an internal node within a Merkle tree
 */
Compute the value of an internal node within a Merkle tree
Compute the value of an internal node within a Merkle tree
static enum hss_error_code hss_compute_internal_node( unsigned char *dest,
                            merkle_index_t node_num, 
                            const unsigned char *seed,
                            param_set_t lm_type,
                            param_set_t lm_ots_type,
                            unsigned h,
                            unsigned leaf_level,
                            const unsigned char *I) {
    unsigned hash_size = hss_hash_length(h);
    unsigned char stack[ MAX_HASH * MAX_MERKLE_HEIGHT];
    merkle_index_t tree_size = (merkle_index_t)1 << leaf_level;
    merkle_index_t r = node_num;
    unsigned levels_to_bottom = 0;
    if (r == 0) return hss_error_internal;  
    while (r < tree_size) {
        r <<= 1;
        levels_to_bottom++;
    }
    merkle_index_t q = r - tree_size;
    merkle_index_t i;
    unsigned ots_len = lm_ots_get_public_key_len(lm_ots_type);
    unsigned char pub_key[ LEAF_MAX_LEN ];
    memcpy( pub_key + LEAF_I, I, I_LEN );
    SET_D( pub_key + LEAF_D, D_LEAF );
    struct seed_derive derive;
    if (!hss_seed_derive_init( &derive, lm_type, lm_ots_type,
                               I, seed)) {
        return hss_error_bad_param_set;
    }
    for (i=0;; i++, r++, q++) {
        hss_seed_derive_set_q( &derive, q );
        if (!lm_ots_generate_public_key(lm_ots_type, I,
                   q, &derive, pub_key + LEAF_PK, ots_len)) {
            return hss_error_bad_param_set; 
        }
        unsigned char *current_buf;
        int stack_offset = trailing_1_bits( i );
        if (stack_offset == levels_to_bottom) {
            current_buf = dest;
        } else {
            current_buf = &stack[stack_offset * hash_size ];
        }
        put_bigendian( pub_key + LEAF_R, r, 4);
        union hash_context ctx;
        hss_hash_ctx( current_buf, h, &ctx, pub_key, LEAF_LEN(hash_size) );
        unsigned sp;
        for (sp = 1; sp <= stack_offset; sp++) {
            hss_combine_internal_nodes( current_buf,
                            &stack[(sp-1) * hash_size], current_buf,
                            h, I, hash_size,
                            r >> sp );
        }
        if (stack_offset == levels_to_bottom) {
            break;
        }
    }
    hss_seed_derive_done( &derive );
    return hss_error_none;
}
static enum hss_error_code hss_compute_internal_node ( unsigned char * dest , merkle_index_t node_num , const unsigned char * seed , param_set_t lm_type , param_set_t lm_ots_type , unsigned h , unsigned leaf_level , const unsigned char * I ) { unsigned hash_size = hss_hash_length ( h ) ; unsigned char stack [ MAX_HASH * MAX_MERKLE_HEIGHT ] ; merkle_index_t tree_size = ( merkle_index_t ) 1 << leaf_level ; merkle_index_t r = node_num ; unsigned levels_to_bottom = 0 ; if ( r == 0 ) return hss_error_internal ; while ( r < tree_size ) { r <<= 1 ; levels_to_bottom ++ ; } merkle_index_t q = r - tree_size ; merkle_index_t i ; unsigned ots_len = lm_ots_get_public_key_len ( lm_ots_type ) ; unsigned char pub_key [ LEAF_MAX_LEN ] ; memcpy ( pub_key + LEAF_I , I , I_LEN ) ; SET_D ( pub_key + LEAF_D , D_LEAF ) ; struct seed_derive derive ; if ( ! hss_seed_derive_init ( & derive , lm_type , lm_ots_type , I , seed ) ) { return hss_error_bad_param_set ; } for ( i = 0 ; ; i ++ , r ++ , q ++ ) { hss_seed_derive_set_q ( & derive , q ) ; if ( ! lm_ots_generate_public_key ( lm_ots_type , I , q , & derive , pub_key + LEAF_PK , ots_len ) ) { return hss_error_bad_param_set ; } unsigned char * current_buf ; int stack_offset = trailing_1_bits ( i ) ; if ( stack_offset == levels_to_bottom ) { current_buf = dest ; } else { current_buf = & stack [ stack_offset * hash_size ] ; } put_bigendian ( pub_key + LEAF_R , r , 4 ) ; union hash_context ctx ; hss_hash_ctx ( current_buf , h , & ctx , pub_key , LEAF_LEN ( hash_size ) ) ; unsigned sp ; for ( sp = 1 ; sp <= stack_offset ; sp ++ ) { hss_combine_internal_nodes ( current_buf , & stack [ ( sp - 1 ) * hash_size ] , current_buf , h , I , hash_size , r >> sp ) ; } if ( stack_offset == levels_to_bottom ) { break ; } } hss_seed_derive_done ( & derive ) ; return hss_error_none ; }
Compute the value of an internal node within a Merkle tree
Compute the value of an internal node within a Merkle tree
/* We're store intermediate nodes here */ /* So no to infinite loops */ /* Generate the next OTS public key */ /* The only reason the above */ /* could fail */ /*
         * For the subtree which this leaf node forms the final piece, put the
         * destination to where we'll want it, either on the stack, or if this
         * is the final piece, to where the caller specified
         */ /* Hash it to form the leaf node */ /* Work up the stack, combining right nodes with the left nodes */ /* that we've already computed */ /* We're not at a left branch, or at the target node */ /* Because we've set current_buf to point to where we want to place */ /* the result of this loop, we don't need to memcpy it */ /* Check if this was the last leaf (and so we've just computed the */ /* target node) */ /* We're at the target node; the node we were asked to compute */ /* We've already placed the value into dest, so we're all done */