question: public List < TLV > initRespondSmp ( String question , String secret , boolean initiating ) throws OtrException { if ( question != null && ! initiating ) throw new IllegalArgumentException ( "Only supply a question if initiating" ) ; byte [ ] our_fp = Hex . decode ( keyManager . getLocalFingerprint ( sessionID ) ) ; String remoteFingerprint = keyManager . getRemoteFingerprint ( sessionID ) ; if ( remoteFingerprint == null ) throw new OtrException ( "no fingerprint for remote user" ) ; byte [ ] their_fp = Hex . decode ( remoteFingerprint ) ; byte [ ] sessionId ; try { sessionId = computeSessionId ( session . getS ( ) ) ; } catch ( SMException ex ) { throw new OtrException ( ex ) ; } byte [ ] bytes = secret . getBytes ( SerializationUtils . UTF8 ) ; int combined_buf_len = 41 + sessionId . length + bytes . length ; byte [ ] combined_buf = new byte [ combined_buf_len ] ; combined_buf [ 0 ] = 1 ; if ( initiating ) { System . arraycopy ( our_fp , 0 , combined_buf , 1 , 20 ) ; System . arraycopy ( their_fp , 0 , combined_buf , 21 , 20 ) ; } else { System . arraycopy ( their_fp , 0 , combined_buf , 1 , 20 ) ; System . arraycopy ( our_fp , 0 , combined_buf , 21 , 20 ) ; } System . arraycopy ( sessionId , 0 , combined_buf , 41 , sessionId . length ) ; System . arraycopy ( bytes , 0 , combined_buf , 41 + sessionId . length , bytes . length ) ; MessageDigest sha256 ; try { sha256 = MessageDigest . getInstance ( "SHA-256" ) ; } catch ( NoSuchAlgorithmException ex ) { throw new OtrException ( ex ) ; } byte [ ] combined_secret = sha256 . digest ( combined_buf ) ; byte [ ] smpmsg ; try { if ( initiating ) { smpmsg = SM . step1 ( smstate , combined_secret ) ; } else { smpmsg = SM . step2b ( smstate , combined_secret ) ; } } catch ( SMException ex ) { throw new OtrException ( ex ) ; } if ( question != null ) { bytes = question . getBytes ( SerializationUtils . UTF8 ) ; byte [ ] qsmpmsg = new byte [ bytes . length + 1 + smpmsg . length ] ; System . arraycopy ( bytes , 0 , qsmpmsg , 0 , bytes . length ) ; System . arraycopy ( smpmsg , 0 , qsmpmsg , bytes . length + 1 , smpmsg . length ) ; smpmsg = qsmpmsg ; } TLV sendtlv = new TLV ( initiating ? ( question != null ? TLV . SMP1Q : TLV . SMP1 ) : TLV . SMP2 , smpmsg ) ; smstate . nextExpected = initiating ? SM . EXPECT2 : SM . EXPECT3 ; return makeTlvList ( sendtlv ) ; }
target:  Respond to or initiate an SMP negotiation