lopy4/components/hash-sigs-master/hss_derive.c
/* This sets the internal 'q' value for seed derivation object */
/* This also updates our internal q-path (the q_index/q_seed arrays) */
/* to reflect the new 'q' value, while minimizing the number of hashes */
/* done (by reusing as much of the previous path as possible) */
This sets the internal 'q' value for seed derivation object
This also updates our internal q-path (the q_index/q_seed arrays)
to reflect the new 'q' value, while minimizing the number of hashes
done (by reusing as much of the previous path as possible)
This sets the internal ' q ' value for seed derivation object This also updates our internal q - path ( the q_index / q_seed arrays ) to reflect the new ' q ' value while minimizing the number of hashes done ( by reusing as much of the previous path as possible )
void hss_seed_derive_set_q( struct seed_derive *derive, merkle_index_t q ) {
    merkle_index_t change = q ^ derive->q;
    derive->q = q;
    unsigned bits_change = my_log2(change);
    unsigned q_levels = derive->q_levels;
    unsigned levels_change = (bits_change + SECRET_MAX - 1) / SECRET_MAX;
    if (levels_change > q_levels) levels_change = q_levels;
    int i;
    union hash_context ctx;
    unsigned char buffer[ QTREE_MAX_LEN ];
    merkle_index_t r = q | derive->r_mask;
    for (i = levels_change; i > 0; i--) {
        int j = q_levels - i;
        int shift = (i-1) * SECRET_MAX;
        memcpy( buffer + QTREE_I, derive->I, I_LEN );
        put_bigendian( buffer + QTREE_Q, r >> shift, 4 );
        SET_D( buffer + QTREE_D, D_QTREE );
        if (j == 0) {
            memcpy( buffer + QTREE_SEED, derive->master_seed, SEED_LEN );
        } else {
            memcpy( buffer + QTREE_SEED, derive->q_seed[j-1], SEED_LEN );
        }
        hss_hash_ctx( derive->q_seed[j], HASH, &ctx, buffer, QTREE_LEN );
    }
    hss_zeroize( buffer, PRG_LEN(SEED_LEN) );
    hss_zeroize( &ctx, sizeof ctx );
}
void hss_seed_derive_set_q ( struct seed_derive * derive , merkle_index_t q ) { merkle_index_t change = q ^ derive -> q ; derive -> q = q ; unsigned bits_change = my_log2 ( change ) ; unsigned q_levels = derive -> q_levels ; unsigned levels_change = ( bits_change + SECRET_MAX - 1 ) / SECRET_MAX ; if ( levels_change > q_levels ) levels_change = q_levels ; int i ; union hash_context ctx ; unsigned char buffer [ QTREE_MAX_LEN ] ; merkle_index_t r = q | derive -> r_mask ; for ( i = levels_change ; i > 0 ; i -- ) { int j = q_levels - i ; int shift = ( i - 1 ) * SECRET_MAX ; memcpy ( buffer + QTREE_I , derive -> I , I_LEN ) ; put_bigendian ( buffer + QTREE_Q , r >> shift , 4 ) ; SET_D ( buffer + QTREE_D , D_QTREE ) ; if ( j == 0 ) { memcpy ( buffer + QTREE_SEED , derive -> master_seed , SEED_LEN ) ; } else { memcpy ( buffer + QTREE_SEED , derive -> q_seed [ j - 1 ] , SEED_LEN ) ; } hss_hash_ctx ( derive -> q_seed [ j ] , HASH , & ctx , buffer , QTREE_LEN ) ; } hss_zeroize ( buffer , PRG_LEN ( SEED_LEN ) ) ; hss_zeroize ( & ctx , sizeof ctx ) ; }
This sets the internal 'q' value for seed derivation object
This also updates our internal q-path (the q_index/q_seed arrays)
to reflect the new 'q' value, while minimizing the number of hashes
done (by reusing as much of the previous path as possible)
This sets the internal ' q ' value for seed derivation object This also updates our internal q - path ( the q_index / q_seed arrays ) to reflect the new ' q ' value while minimizing the number of hashes done ( by reusing as much of the previous path as possible )
/* levels_change will be the number of levels of the q-tree we'll */ /* need to recompute */