@@ -126,7 +126,7 @@ protected MbedTLS.HMAC CreateHMAC(byte[] key)
126126 return new MbedTLS . HMAC_MD5 ( key ) ;
127127 }
128128
129- protected int GetRandLen ( int datalength , xorshift128plus random , byte [ ] last_hash )
129+ protected virtual int GetRandLen ( int datalength , xorshift128plus random , byte [ ] last_hash )
130130 {
131131 if ( datalength > 1440 )
132132 return 0 ;
@@ -545,9 +545,116 @@ public override byte[] ClientUdpPostDecrypt(byte[] plaindata, int datalength, ou
545545 encryptor . Decrypt ( plaindata , outlength , plaindata , out outlength ) ;
546546 return plaindata ;
547547 }
548+ }
549+
550+ class AuthChain_b : AuthChain_a
551+ {
552+ public AuthChain_b ( string method )
553+ : base ( method )
554+ {
555+
556+ }
557+
558+ private static Dictionary < string , int [ ] > _obfs = new Dictionary < string , int [ ] > {
559+ { "auth_chain_b" , new int [ ] { 1 , 0 , 1 } } ,
560+ } ;
561+
562+ protected int [ ] data_size_list = null ;
563+ protected int [ ] data_size_list2 = null ;
564+
565+ public static new List < string > SupportedObfs ( )
566+ {
567+ return new List < string > ( _obfs . Keys ) ;
568+ }
569+
570+ public override Dictionary < string , int [ ] > GetObfs ( )
571+ {
572+ return _obfs ;
573+ }
574+
575+ protected void InitDataSizeList ( )
576+ {
577+ xorshift128plus random = new xorshift128plus ( ) ;
578+ random . init_from_bin ( Server . key ) ;
579+ int len = ( int ) ( random . next ( ) % 8 + 4 ) ;
580+ List < int > data_list = new List < int > ( ) ;
581+ for ( int i = 0 ; i < len ; ++ i )
582+ {
583+ data_list . Add ( ( int ) ( random . next ( ) % 2340 % 2040 % 1440 ) ) ;
584+ }
585+ data_list . Sort ( ) ;
586+ data_size_list = data_list . ToArray ( ) ;
587+
588+ len = ( int ) ( random . next ( ) % 16 + 8 ) ;
589+ data_list . Clear ( ) ;
590+ for ( int i = 0 ; i < len ; ++ i )
591+ {
592+ data_list . Add ( ( int ) ( random . next ( ) % 2340 % 2040 % 1440 ) ) ;
593+ }
594+ data_list . Sort ( ) ;
595+ data_size_list2 = data_list . ToArray ( ) ;
596+ }
597+
598+ public override void SetServerInfo ( ServerInfo serverInfo )
599+ {
600+ Server = serverInfo ;
601+ InitDataSizeList ( ) ;
602+ }
548603
549- public override void Dispose ( )
604+ protected int FindPos ( int [ ] arr , int key )
550605 {
606+ int low = 0 ;
607+ int high = arr . Length - 1 ;
608+ int middle = - 1 ;
609+
610+ if ( key > arr [ high ] )
611+ return arr . Length ;
612+
613+ while ( low < high )
614+ {
615+ middle = ( low + high ) / 2 ;
616+ if ( key > arr [ middle ] )
617+ {
618+ low = middle + 1 ;
619+ }
620+ else if ( key <= arr [ middle ] )
621+ {
622+ high = middle ;
623+ }
624+ }
625+ return low ;
626+ }
627+
628+ protected override int GetRandLen ( int datalength , xorshift128plus random , byte [ ] last_hash )
629+ {
630+ if ( datalength >= 1440 )
631+ return 0 ;
632+ random . init_from_bin ( last_hash , datalength ) ;
633+
634+ int pos = FindPos ( data_size_list , datalength + Server . overhead ) ;
635+ int final_pos = pos + ( int ) ( random . next ( ) % ( ulong ) ( data_size_list . Length ) ) ;
636+ if ( final_pos < data_size_list . Length )
637+ {
638+ return data_size_list [ final_pos ] - datalength - Server . overhead ;
639+ }
640+
641+ pos = FindPos ( data_size_list2 , datalength + Server . overhead ) ;
642+ final_pos = pos + ( int ) ( random . next ( ) % ( ulong ) ( data_size_list2 . Length ) ) ;
643+ if ( final_pos < data_size_list2 . Length )
644+ {
645+ return data_size_list2 [ final_pos ] - datalength - Server . overhead ;
646+ }
647+ if ( final_pos < pos + data_size_list2 . Length - 1 )
648+ {
649+ return 0 ;
650+ }
651+ if ( datalength > 1300 )
652+ return ( int ) ( random . next ( ) % 31 ) ;
653+ if ( datalength > 900 )
654+ return ( int ) ( random . next ( ) % 127 ) ;
655+ if ( datalength > 400 )
656+ return ( int ) ( random . next ( ) % 521 ) ;
657+ return ( int ) ( random . next ( ) % 1021 ) ;
551658 }
552659
553660 }
0 commit comments