             return nil;
             
         }
+        if recv_ctx == nil && encrypt_bytes.length < 16 {
+            AxLogger.log("socket read less iv_len",level: .Error)
+        }
         
         if let left = genData(encrypt_bytes) {
             
             // Alloc Data Out
-            let cipherDataDecrypt:NSMutableData = NSMutableData.init(length: left.length)!;
-            
-            //alloc number of bytes written to data Out
-            var  outLengthDecrypt:NSInteger = 0
-            
-            //Update Cryptor
-            let updateDecrypt:CCCryptorStatus = CCCryptorUpdate(recv_ctx!.ctx,
-                                                                left.bytes, //const void *dataIn,
-                left.length,  //size_t dataInLength,
-                cipherDataDecrypt.mutableBytes, //void *dataOut,
-                cipherDataDecrypt.length, // size_t dataOutAvailable,
-                &outLengthDecrypt); // size_t *dataOutMoved)
-            
-            if (updateDecrypt == CCCryptorStatus(kCCSuccess))
-            {
-                //Cut Data Out with nedded length
-                cipherDataDecrypt.length = outLengthDecrypt;
-                
-                // Data to String
-                //NSString* cipherFinalDecrypt = [[NSString alloc] initWithData:cipherDataDecrypt encoding:NSUTF8StringEncoding];
-                
-                //Final Cryptor
-                let final:CCCryptorStatus = CCCryptorFinal(recv_ctx!.ctx, //CCCryptorRef cryptorRef,
+            guard let  ctx =  recv_ctx else {
+                print("ctx error")
+                AxLogger.log("socket read less iv_len",level: .Error)
+                return nil }
+            
+            if ctx.m.rawValue >= CryptoMethod.SALSA20.rawValue {
+                print("iv \(ctx.IV)")
+                print("ramdonKey \(ramdonKey!)")
+                print("data \(left)")
+                let padding = ctx.counter % SODIUM_BLOCK_SIZE;
+                let cipher = NSMutableData.init(length:  left.length + Int(padding))
+                
+                //cipher.length += encrypt_bytes.length
+                //            brealloc(cipher, iv_len + (padding + cipher->len) * 2, capacity);
+                var  plain:NSMutableData
+                if padding != 0 {
+                    plain = NSMutableData.init(length: Int(padding))!
+                    plain.appendData(left)
+                    //plain.length =  plain.length + Int(padding)
+                    //                brealloc(plain, plain->len + padding, capacity);
+                    //                memmove(plain->array + padding, plain->array, plain->len);
+                    //sodium_memzero(plain->array, padding);
+                }else {
+                    plain = NSMutableData.init(data: left)
+                }
+                //let enc_key = NSMutableData.init(data: ramdonKey!)
+                //enc_key.length = ctx.m.key_size
+                //            let ptr:UnsafeMutablePointer<UInt8> = UnsafeMutablePointer<UInt8>.init((cipher?.mutableBytes)!)
+                //            let ptr2:UnsafePointer<UInt8> = UnsafePointer<UInt8>.init(encrypt_bytes.bytes)
+                //let vvv = NSMutableData.init(data: ctx.IV)
+                //vvv.length = 16
+                crypto_stream_xor_ic(cipher! ,
+                                     md: plain,
+                                     mlen: UInt64(plain.length),
+                                     nd: ctx.IV,
+                                     ic: ctx.counter / SODIUM_BLOCK_SIZE,
+                                     kd: ramdonKey!)
+               
+                
+                print("padding \(padding) cipher \(cipher!)")
+                ctx.counter += UInt64(left.length)
+                
+                 
+                
+                let result = cipher!.subdataWithRange(NSMakeRange(Int(padding), left.length + Int(padding) ))
+                
+                return result
+                
+                
+                //todo add
+//                int padding = ctx->counter % SODIUM_BLOCK_SIZE;
+//                brealloc(plain, (plain->len + padding) * 2, capacity);
+//                
+//                if (padding) {
+//                    brealloc(cipher, cipher->len + padding, capacity);
+//                    memmove(cipher->array + iv_len + padding, cipher->array + iv_len,
+//                        cipher->len - iv_len);
+//                    sodium_memzero(cipher->array + iv_len, padding);
+//                }
+//                crypto_stream_xor_ic((uint8_t *)plain->array,
+//                    (const uint8_t *)(cipher->array + iv_len),
+//                    (uint64_t)(cipher->len - iv_len + padding),
+//                    (const uint8_t *)ctx->evp.iv,
+//                    ctx->counter / SODIUM_BLOCK_SIZE, enc_key,
+//                    enc_method);
+//                ctx->counter += cipher->len - iv_len;
+//                if (padding) {
+//                    memmove(plain->array, plain->array + padding, plain->len);
+//                }
+
+            }else {
+                let cipherDataDecrypt:NSMutableData = NSMutableData.init(length: left.length)!;
+                
+                //alloc number of bytes written to data Out
+                var  outLengthDecrypt:NSInteger = 0
+                
+                //Update Cryptor
+                let updateDecrypt:CCCryptorStatus = CCCryptorUpdate(ctx.ctx,
+                                                                    left.bytes, //const void *dataIn,
+                    left.length,  //size_t dataInLength,
                     cipherDataDecrypt.mutableBytes, //void *dataOut,
                     cipherDataDecrypt.length, // size_t dataOutAvailable,
                     &outLengthDecrypt); // size_t *dataOutMoved)
                 
-                if (final != CCCryptorStatus( kCCSuccess))
+                if (updateDecrypt == CCCryptorStatus(0))
                 {
-                    logStream.write("decrypt CCCryptorFinal failure")
-                    //Release Cryptor
-                    //CCCryptorStatus release =
-                    //CCCryptorRelease(cryptor); //CCCryptorRef cryptorRef
+                    //Cut Data Out with nedded length
+                    cipherDataDecrypt.length = outLengthDecrypt;
+                    
+                    // Data to String
+                    //NSString* cipherFinalDecrypt = [[NSString alloc] initWithData:cipherDataDecrypt encoding:NSUTF8StringEncoding];
+                    
+                    //Final Cryptor
+                    let final:CCCryptorStatus = CCCryptorFinal(ctx.ctx, //CCCryptorRef cryptorRef,
+                        cipherDataDecrypt.mutableBytes, //void *dataOut,
+                        cipherDataDecrypt.length, // size_t dataOutAvailable,
+                        &outLengthDecrypt); // size_t *dataOutMoved)
+                    
+                    if (final != CCCryptorStatus( 0))
+                    {
+                        AxLogger.log("decrypt CCCryptorFinal failure")
+                        //Release Cryptor
+                        //CCCryptorStatus release =
+                        //CCCryptorRelease(cryptor); //CCCryptorRef cryptorRef
+                    }
+                    
+                    return cipherDataDecrypt ;//cipherFinalDecrypt;
+                }else {
+                    print("111 decrypt no Data")
+                    AxLogger.log("decrypt CCCryptorUpdate failure")
                 }
-                
-                return cipherDataDecrypt ;//cipherFinalDecrypt;
-            }else {
-                
-                logStream.write("decrypt CCCryptorUpdate failure")
-            }
+
+            }
+            
         }else {
-            logStream.write("decrypt no Data")
+            print("000 decrypt no Data")
+            AxLogger.log("decrypt no Data")
         }
         
         
         
         return nil
     }
-    func getSecureRandom(bytesCount:Int) ->NSData {
+    static func getSecureRandom(bytesCount:Int) ->NSData {
         // Swift
         //import Security
         

        
        //let encrypt_bytes = padding(encrypt_bytes_org)
        //alloc number of bytes written to data Out
        var  outLength:NSInteger = 0 ;
        // Alloc Data Out
        let cipherData:NSMutableData = NSMutableData.init(length: encrypt_bytes.length)!;
        //Update Cryptor
        let  update:CCCryptorStatus = CCCryptorUpdate(send_ctx!.ctx,
                                                      encrypt_bytes.bytes,
                                                      encrypt_bytes.length,
                                                      cipherData.mutableBytes,
                                                      cipherData.length,
                                                      &outLength);
        if (update == CCCryptorStatus(kCCSuccess))
        {
            //Cut Data Out with nedded length
            cipherData.length = outLength;
            
            //Final Cryptor
            let final:CCCryptorStatus = CCCryptorFinal(send_ctx!.ctx, //CCCryptorRef cryptorRef,
                cipherData.mutableBytes, //void *dataOut,
                cipherData.length, // size_t dataOutAvailable,
                &outLength); // size_t *dataOutMoved)
            
            if (final == CCCryptorStatus(kCCSuccess))
            {
                
                //CCCryptorRelease(cryptor )
            }
            if send_ctx!.count == 0 {
                send_ctx!.count += 1
                let d:NSMutableData = NSMutableData()
                d.appendData(send_ctx!.IV);
                
                d.appendData(cipherData)
                return d
            }else {
                return cipherData
            }
            
            //AxLogger.log("cipher length:\(d.length % 16)")
            
            
        }
        
        return nil
    }
    
}

        // Turn bytes into data and pass data bytes into int
        return NSData(bytes: randomBytes, length: bytesCount) //getBytes(&randomNum, length: bytesCount)
    }
//    func padding(d:NSData) ->NSData{
//        let l = d.length % block_size
//        if l != 0 {
//            let x = NSMutableData.init(data: d)
//            x.length += l
//            return x
//        }else {
//            return d
//        }
//    }
    func encrypt(encrypt_bytes:NSData) ->NSData?{
        
        //let iv:NSData = NSData();
