anchor.diff:  
   %%%---- Block ciphers
   %%%----------------------------------------------------------------
  --spec block_encrypt(Type::block_cipher_iv(), Key::key()|des3_key(), Ivec::binary(), PlainText::iodata()) ->
  +-spec block_encrypt(Type::block_cipher_with_iv(), Key::key()|des3_key(), Ivec::binary(), PlainText::iodata()) ->
                              binary() | run_time_error();
                      (Type::aead_cipher(),  Key::iodata(), Ivec::binary(), {AAD::binary(), PlainText::iodata()}) ->
                              {binary(), binary()} | run_time_error();
  
positive.code:                            crypto_state() | {crypto_state(),flg_undefined}
                            }.
  
  -type stream_cipher() :: stream_cipher_iv() | stream_cipher_no_iv() .
  -type stream_cipher_no_iv() :: rc4 .
  -type stream_cipher_iv() :: aes_ctr
                            | aes_128_ctr
                            | aes_192_ctr
                            | aes_256_ctr
                            | chacha20 .
  
  %%%---- stream_init
  -spec stream_init(Type, Key, IVec) -> State | run_time_error()
                                            when Type :: stream_cipher_iv(),
                                                 Key :: iodata(),
                                                 IVec ::binary(),
                                                 State :: stream_state() .
  
negative.code: %%% The size must be an integer multiple of the crypto's blocksize.
  %%% 
  
  -spec crypto_one_time(Cipher, Key, Data, EncryptFlag) ->
                               Result | descriptive_error()
                                   when Cipher :: cipher_no_iv(),
                                        Key :: iodata(),
                                        Data :: iodata(),
                                        EncryptFlag :: boolean(),
                                        Result :: binary() .
  
  crypto_one_time(Cipher, Key, Data, EncryptFlag) ->
      crypto_one_time(Cipher, Key, <<>>, Data, EncryptFlag).
  
  -spec crypto_one_time(Cipher, Key, IV, Data, EncryptFlag) ->
                               Result | descriptive_error()
                                   when Cipher :: cipher_iv(),
                                        Key :: iodata(),
                                        IV :: iodata(),
                                        Data :: iodata(),
                                        EncryptFlag :: boolean(),
                                        Result :: binary() .
  
  crypto_one_time(Cipher, Key, IV, Data0, EncryptFlag) ->
      case iolist_to_binary(Data0) of
          <<>> ->
              <<>>;                           % Known to fail on OpenSSL 0.9.8h
          Data ->
              ng_crypto_one_time_nif(Cipher,
                                     iolist_to_binary(Key), iolist_to_binary(IV), Data,
                                     EncryptFlag)
      end.
  
  
  -spec crypto_aead(Cipher, Key, IV, InText, AAD, EncFlag::true) ->
                               Result | descriptive_error()
                                   when Cipher :: cipher_aead(),
                                        Key :: iodata(),
                                        IV :: iodata(),
                                        InText :: iodata(),
                                        AAD :: iodata(),
                                        Result :: EncryptResult,
                                        EncryptResult :: {OutCryptoText, OutTag},
                                        OutCryptoText :: binary(),
                                        OutTag :: binary().
  
  crypto_aead(Cipher, Key, IV, PlainText, AAD, true) ->
      crypto_aead(Cipher, Key, IV, PlainText, AAD, aead_tag_len(Cipher), true).
  
  
  -spec crypto_aead(Cipher, Key, IV, InText, AAD, TagOrTagLength, EncFlag) ->
                               Result | descriptive_error()
                                   when Cipher :: cipher_aead(),
                                        Key :: iodata(),
                                        IV :: iodata(),
                                        InText :: iodata(),
                                        AAD :: iodata(),
                                        TagOrTagLength :: EncryptTagLength | DecryptTag,
                                        EncryptTagLength :: non_neg_integer(), % or pos_integer() 1..
                                        DecryptTag :: iodata(),
                                        EncFlag :: boolean(),
                                        Result :: EncryptResult | DecryptResult,
                                        EncryptResult :: {OutCryptoText, OutTag},
                                        DecryptResult :: OutPlainText | error,
                                        OutCryptoText :: binary(),
                                        OutTag :: binary(),
                                        OutPlainText :: binary().
  
  crypto_aead(Cipher, Key, IV, TextIn, AAD, TagOrTagLength, EncFlg) ->
      aead_cipher(Cipher, Key, IV, TextIn, AAD, TagOrTagLength, EncFlg).
  
  
  aead_tag_len(chacha20_poly1305) -> 16;
  aead_tag_len(aes_ccm    ) -> 12;
  aead_tag_len(aes_128_ccm) -> 12;
  aead_tag_len(aes_192_ccm) -> 12;
  aead_tag_len(aes_256_ccm) -> 12;
  aead_tag_len(aes_gcm    ) -> 16;
  aead_tag_len(aes_128_gcm) -> 16;
  aead_tag_len(aes_192_gcm) -> 16;
  aead_tag_len(aes_256_gcm) -> 16;
  aead_tag_len(_) -> error({badarg, "Not an AEAD cipher"}).
  
  %%%----------------------------------------------------------------
  %%% NIFs
  