question: private byte [ ] PSHA ( byte [ ] secret , String label , byte [ ] data , int offset , int length ) throws ServiceResultException { if ( secret == null ) throw new IllegalArgumentException ( "ArgumentNullException: secret" ) ; if ( offset < 0 ) throw new IllegalArgumentException ( "ArgumentOutOfRangeException: offset" ) ; if ( length < 0 ) throw new IllegalArgumentException ( "ArgumentOutOfRangeException: offset" ) ; byte [ ] seed = label != null && ! label . isEmpty ( ) ? label . getBytes ( UTF8 ) : null ; if ( data != null && data . length > 0 ) { if ( seed != null ) { ByteBuffer buf = ByteBuffer . allocate ( seed . length + data . length ) ; buf . put ( seed ) ; buf . put ( data ) ; buf . rewind ( ) ; seed = buf . array ( ) ; } else { seed = data ; } } if ( seed == null ) { throw new ServiceResultException ( StatusCodes . Bad_UnexpectedError , "The PSHA algorithm requires a non-null seed." ) ; } SecurityPolicy policy = securityConfiguration . getSecurityPolicy ( ) ; Mac hmac = CryptoUtil . createMac ( policy . getKeyDerivationAlgorithm ( ) , secret ) ; hmac . update ( seed ) ; byte [ ] keySeed = hmac . doFinal ( ) ; byte [ ] prfSeed = new byte [ hmac . getMacLength ( ) + seed . length ] ; System . arraycopy ( keySeed , 0 , prfSeed , 0 , keySeed . length ) ; System . arraycopy ( seed , 0 , prfSeed , keySeed . length , seed . length ) ; byte [ ] output = new byte [ length ] ; int position = 0 ; do { hmac . update ( prfSeed ) ; byte [ ] hash = hmac . doFinal ( ) ; if ( offset < hash . length ) { for ( int ii = offset ; position < length && ii < hash . length ; ii ++ ) { output [ position ++ ] = hash [ ii ] ; } } if ( offset > hash . length ) { offset -= hash . length ; } else { offset = 0 ; } hmac . update ( keySeed ) ; keySeed = hmac . doFinal ( ) ; System . arraycopy ( keySeed , 0 , prfSeed , 0 , keySeed . length ) ; } while ( position < length ) ; return output ; }
target:  Generates a Pseudo random sequence of bits using the P_SHA1 or P_SHA256 alhorithm. This function conforms with C#-implementation, so that keys returned  from this function matches the C#-implementation keys.