diff --git a/plugin/world/blowfish_ecb/LICENSE.txt b/plugin/world/blowfish_ecb/LICENSE.txt
new file mode 100644
index 00000000..49cc83d2
--- /dev/null
+++ b/plugin/world/blowfish_ecb/LICENSE.txt
@@ -0,0 +1,177 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        https://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
diff --git a/plugin/world/blowfish_ecb/README.md b/plugin/world/blowfish_ecb/README.md
new file mode 100644
index 00000000..ebf37cec
--- /dev/null
+++ b/plugin/world/blowfish_ecb/README.md
@@ -0,0 +1,10 @@
+# Blowfish-ECB
+
+Port of OpenSSL's Blowfish implementation for Ruby.
+
+Created to workaround an issue of Ruby which prevents using deprecated OpenSSL APIs, including the Blowfish algorithm.
+
+## Copyrights
+Copyright (c) 1998-2023 The OpenSSL Project Authors
+
+Copyright (c) 1995-1998 Eric A. Young, Tim J. Hudson
\ No newline at end of file
diff --git a/plugin/world/blowfish_ecb/blowfish_ecb.rb b/plugin/world/blowfish_ecb/blowfish_ecb.rb
new file mode 100644
index 00000000..bc5d0b54
--- /dev/null
+++ b/plugin/world/blowfish_ecb/blowfish_ecb.rb
@@ -0,0 +1,6 @@
+module Blowfish
+  module ECB
+  end
+end
+
+require_relative 'lib/cipher'
\ No newline at end of file
diff --git a/plugin/world/blowfish_ecb/lib/cipher.rb b/plugin/world/blowfish_ecb/lib/cipher.rb
new file mode 100644
index 00000000..bc503d51
--- /dev/null
+++ b/plugin/world/blowfish_ecb/lib/cipher.rb
@@ -0,0 +1,44 @@
+require_relative 'ecb'
+require_relative 'key'
+
+module Blowfish::ECB
+  class Cipher
+    # call-seq:
+    #   Blowfish::ECB::Cipher.new(string) -> Cipher
+    #
+    # Creates a Cipher instance with given key.
+    def initialize(key)
+      @key = Blowfish::ECB::Key.new(key)
+    end
+
+    # call-seq:
+    #   cipher.encrypt(string) -> string
+    #
+    # Encrypts given data.
+    def encrypt(data)
+      bytes = data.unpack("C*")
+      pad_len = 8 - (bytes.size % 8)
+      bytes.push(*([pad_len] * pad_len))
+      Blowfish::ECB.encrypt(bytes.pack("C*"), @key)
+    end
+
+    # call-seq:
+    #   cipher.decrypt(string) -> string
+    #
+    # Decrypts given data. The data must be in ASCII-8BIT encoding, since the
+    # encrypted data consists of arbitrary bytes. It is a sign of a bug if the
+    # encrypted data is encoded as if it was a human-readable text.
+    def decrypt(data)
+      if data.encoding != Encoding::ASCII_8BIT
+        raise "data.encoding must be ASCII-8BIT, but got: #{data.encoding}"
+      end
+
+      decoded = Blowfish::ECB.decrypt(data, @key)
+
+      # Last byte indicates the size of padding.
+      # Strip the padding from res accordingly.
+      pad_len = decoded[-1].unpack("C")[0]
+      decoded[0...-pad_len]
+    end
+  end
+end
diff --git a/plugin/world/blowfish_ecb/lib/common.rb b/plugin/world/blowfish_ecb/lib/common.rb
new file mode 100644
index 00000000..0bafe77b
--- /dev/null
+++ b/plugin/world/blowfish_ecb/lib/common.rb
@@ -0,0 +1,85 @@
+module Blowfish::ECB::Common
+  class << self
+    # call-seq:
+    #   encrypt(l, r, Key) -> [int, int]
+    #
+    # Encrypts pseudo-64bit-value (l, r) into bytes using given key.
+    # Both l and r must be 32-bit integers.
+    # Original: https://github.com/openssl/openssl/blob/e8e2b131ca253f9e28c511c8294e27ddbd0b60c6/crypto/bf/bf_enc.c#L30
+    #
+    # Note that unlike the original implementation, this method returns a new tuple representing the result
+    # rather than destructively updating the input argument. 
+    def encrypt(l, r, key)
+      l ^= key.p[0]
+      r = bf_enc(r, l, key.s, key.p[1])
+      l = bf_enc(l, r, key.s, key.p[2])
+      r = bf_enc(r, l, key.s, key.p[3])
+      l = bf_enc(l, r, key.s, key.p[4])
+      r = bf_enc(r, l, key.s, key.p[5])
+      l = bf_enc(l, r, key.s, key.p[6])
+      r = bf_enc(r, l, key.s, key.p[7])
+      l = bf_enc(l, r, key.s, key.p[8])
+      r = bf_enc(r, l, key.s, key.p[9])
+      l = bf_enc(l, r, key.s, key.p[10])
+      r = bf_enc(r, l, key.s, key.p[11])
+      l = bf_enc(l, r, key.s, key.p[12])
+      r = bf_enc(r, l, key.s, key.p[13])
+      l = bf_enc(l, r, key.s, key.p[14])
+      r = bf_enc(r, l, key.s, key.p[15])
+      l = bf_enc(l, r, key.s, key.p[16])
+      r ^= key.p[17]
+
+      [r & 0xffffffff, l & 0xffffffff]
+    end
+
+    # call-seq:
+    #   decrypt(l, r, Key) -> [int, int]
+    #
+    # Decrypts pseudo-64bit-value (l, r) into bytes using given key.
+    # Both l and r must be 32-bit integers.
+    # Original: https://github.com/openssl/openssl/blob/e8e2b131ca253f9e28c511c8294e27ddbd0b60c6/crypto/bf/bf_enc.c#L69
+    #
+    # Note that unlike the original implementation, this method returns a new tuple representing the result
+    # rather than destructively updating the input argument. 
+    def decrypt(l, r, key)
+      l ^= key.p[17]
+      r = bf_enc(r, l, key.s, key.p[16])
+      l = bf_enc(l, r, key.s, key.p[15])
+      r = bf_enc(r, l, key.s, key.p[14])
+      l = bf_enc(l, r, key.s, key.p[13])
+      r = bf_enc(r, l, key.s, key.p[12])
+      l = bf_enc(l, r, key.s, key.p[11])
+      r = bf_enc(r, l, key.s, key.p[10])
+      l = bf_enc(l, r, key.s, key.p[9])
+      r = bf_enc(r, l, key.s, key.p[8])
+      l = bf_enc(l, r, key.s, key.p[7])
+      r = bf_enc(r, l, key.s, key.p[6])
+      l = bf_enc(l, r, key.s, key.p[5])
+      r = bf_enc(r, l, key.s, key.p[4])
+      l = bf_enc(l, r, key.s, key.p[3])
+      r = bf_enc(r, l, key.s, key.p[2])
+      l = bf_enc(l, r, key.s, key.p[1])
+      r ^= key.p[0]
+
+      [r & 0xffffffff, l & 0xffffffff]
+    end
+
+    private
+
+    # call-seq:
+    #    bf_enc(int, int, [int], int) -> int
+    #
+    # Calculates one step of the Blowfish encryption.
+    # Original: https://github.com/openssl/openssl/blob/e8e2b131ca253f9e28c511c8294e27ddbd0b60c6/crypto/bf/bf_local.h#L76
+    #
+    # Note that due to limitation in Ruby, unlike what the original BF_ENC is doing,
+    # this method returns the calculated value rather than destructively reassigning l.
+    def bf_enc(l, r, s, p)
+      tmp =  s[0x0000+((r>>24)&0xff)]
+      tmp += s[0x0100+((r>>16)&0xff)]
+      tmp ^= s[0x0200+((r>> 8)&0xff)]
+      tmp += s[0x0300+((r    )&0xff)]
+      l ^ p ^ (tmp & 0xffffffff)
+    end
+  end
+end
\ No newline at end of file
diff --git a/plugin/world/blowfish_ecb/lib/ecb.rb b/plugin/world/blowfish_ecb/lib/ecb.rb
new file mode 100644
index 00000000..ea620ddf
--- /dev/null
+++ b/plugin/world/blowfish_ecb/lib/ecb.rb
@@ -0,0 +1,42 @@
+module Blowfish::ECB
+  class << self
+    # call-seq:
+    #   Blowfish::ECB.encrypt(string, Key) -> string
+    #
+    # Encrypts the data (as in byte sequence) with given key.
+    # Since the data is a byte sequence, its encoding must be ASCII-8BIT. 
+    def encrypt(data, key)
+      if data.size % 8 != 0
+        raise "data size must be multiple of 8, but got: #{data.size}"
+      end
+
+      res = ""
+      0.step(data.size - 1, 8).each do |i|
+        l, r = data.byteslice(i, 8).unpack("I>I>")
+        res += Common.encrypt(l, r, key).pack("I>I>")
+      end
+      res
+    end
+
+    # call-seq:
+    #   Blowfish::ECB.decrypt(string, Key) -> string
+    #
+    # Decrypts the data (as in byte sequence) with given key.
+    # Since the data is a byte sequence, its encoding must be ASCII-8BIT. 
+    def decrypt(data, key)
+      if data.encoding != Encoding::ASCII_8BIT
+        raise "data.encoding must be ASCII-8BIT, but got: #{data.encoding}"
+      end
+      if data.size % 8 != 0
+        raise "data size must be multiple of 8, but got: #{data.size}"
+      end
+
+      res = ""
+      0.step(data.size - 1, 8).each do |i|
+        l, r = data.byteslice(i, 8).unpack("I>I>")
+        res += Common.decrypt(l, r, key).pack("I>I>")
+      end
+      res
+    end
+  end
+end
\ No newline at end of file
diff --git a/plugin/world/blowfish_ecb/lib/key.rb b/plugin/world/blowfish_ecb/lib/key.rb
new file mode 100644
index 00000000..6259e3b9
--- /dev/null
+++ b/plugin/world/blowfish_ecb/lib/key.rb
@@ -0,0 +1,572 @@
+require_relative 'common'
+
+module Blowfish::ECB
+  class Key
+    attr_reader :p, :s
+
+    # call-seq:
+    #   Blowfish::ECB::Key.new(string) -> Key
+    #
+    # Returns a Blowfish key object initialized with the given key.
+    # Original: https://github.com/openssl/openssl/blob/456e6ca5d73972cdb4228e6c5ec9acdf19237308/crypto/bf/bf_skey.c
+    def initialize(key)
+      @p = [
+        0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344,
+        0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89,
+        0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
+        0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917,
+        0x9216d5d9, 0x8979fb1b
+      ]
+      @s = [
+        0xd1310ba6, 0x98dfb5ac, 0x2ffd72db,
+        0xd01adfb7,
+        0xb8e1afed, 0x6a267e96, 0xba7c9045,
+        0xf12c7f99,
+        0x24a19947, 0xb3916cf7, 0x0801f2e2,
+        0x858efc16,
+        0x636920d8, 0x71574e69, 0xa458fea3,
+        0xf4933d7e,
+        0x0d95748f, 0x728eb658, 0x718bcd58,
+        0x82154aee,
+        0x7b54a41d, 0xc25a59b5, 0x9c30d539,
+        0x2af26013,
+        0xc5d1b023, 0x286085f0, 0xca417918,
+        0xb8db38ef,
+        0x8e79dcb0, 0x603a180e, 0x6c9e0e8b,
+        0xb01e8a3e,
+        0xd71577c1, 0xbd314b27, 0x78af2fda,
+        0x55605c60,
+        0xe65525f3, 0xaa55ab94, 0x57489862,
+        0x63e81440,
+        0x55ca396a, 0x2aab10b6, 0xb4cc5c34,
+        0x1141e8ce,
+        0xa15486af, 0x7c72e993, 0xb3ee1411,
+        0x636fbc2a,
+        0x2ba9c55d, 0x741831f6, 0xce5c3e16,
+        0x9b87931e,
+        0xafd6ba33, 0x6c24cf5c, 0x7a325381,
+        0x28958677,
+        0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b,
+        0x66282193,
+        0x61d809cc, 0xfb21a991, 0x487cac60,
+        0x5dec8032,
+        0xef845d5d, 0xe98575b1, 0xdc262302,
+        0xeb651b88,
+        0x23893e81, 0xd396acc5, 0x0f6d6ff3,
+        0x83f44239,
+        0x2e0b4482, 0xa4842004, 0x69c8f04a,
+        0x9e1f9b5e,
+        0x21c66842, 0xf6e96c9a, 0x670c9c61,
+        0xabd388f0,
+        0x6a51a0d2, 0xd8542f68, 0x960fa728,
+        0xab5133a3,
+        0x6eef0b6c, 0x137a3be4, 0xba3bf050,
+        0x7efb2a98,
+        0xa1f1651d, 0x39af0176, 0x66ca593e,
+        0x82430e88,
+        0x8cee8619, 0x456f9fb4, 0x7d84a5c3,
+        0x3b8b5ebe,
+        0xe06f75d8, 0x85c12073, 0x401a449f,
+        0x56c16aa6,
+        0x4ed3aa62, 0x363f7706, 0x1bfedf72,
+        0x429b023d,
+        0x37d0d724, 0xd00a1248, 0xdb0fead3,
+        0x49f1c09b,
+        0x075372c9, 0x80991b7b, 0x25d479d8,
+        0xf6e8def7,
+        0xe3fe501a, 0xb6794c3b, 0x976ce0bd,
+        0x04c006ba,
+        0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2,
+        0x196a2463,
+        0x68fb6faf, 0x3e6c53b5, 0x1339b2eb,
+        0x3b52ec6f,
+        0x6dfc511f, 0x9b30952c, 0xcc814544,
+        0xaf5ebd09,
+        0xbee3d004, 0xde334afd, 0x660f2807,
+        0x192e4bb3,
+        0xc0cba857, 0x45c8740f, 0xd20b5f39,
+        0xb9d3fbdb,
+        0x5579c0bd, 0x1a60320a, 0xd6a100c6,
+        0x402c7279,
+        0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8,
+        0xdb3222f8,
+        0x3c7516df, 0xfd616b15, 0x2f501ec8,
+        0xad0552ab,
+        0x323db5fa, 0xfd238760, 0x53317b48,
+        0x3e00df82,
+        0x9e5c57bb, 0xca6f8ca0, 0x1a87562e,
+        0xdf1769db,
+        0xd542a8f6, 0x287effc3, 0xac6732c6,
+        0x8c4f5573,
+        0x695b27b0, 0xbbca58c8, 0xe1ffa35d,
+        0xb8f011a0,
+        0x10fa3d98, 0xfd2183b8, 0x4afcb56c,
+        0x2dd1d35b,
+        0x9a53e479, 0xb6f84565, 0xd28e49bc,
+        0x4bfb9790,
+        0xe1ddf2da, 0xa4cb7e33, 0x62fb1341,
+        0xcee4c6e8,
+        0xef20cada, 0x36774c01, 0xd07e9efe,
+        0x2bf11fb4,
+        0x95dbda4d, 0xae909198, 0xeaad8e71,
+        0x6b93d5a0,
+        0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f,
+        0x8e7594b7,
+        0x8ff6e2fb, 0xf2122b64, 0x8888b812,
+        0x900df01c,
+        0x4fad5ea0, 0x688fc31c, 0xd1cff191,
+        0xb3a8c1ad,
+        0x2f2f2218, 0xbe0e1777, 0xea752dfe,
+        0x8b021fa1,
+        0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6,
+        0xce89e299,
+        0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81,
+        0xd2ada8d9,
+        0x165fa266, 0x80957705, 0x93cc7314,
+        0x211a1477,
+        0xe6ad2065, 0x77b5fa86, 0xc75442f5,
+        0xfb9d35cf,
+        0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3,
+        0xae1e7e49,
+        0x00250e2d, 0x2071b35e, 0x226800bb,
+        0x57b8e0af,
+        0x2464369b, 0xf009b91e, 0x5563911d,
+        0x59dfa6aa,
+        0x78c14389, 0xd95a537f, 0x207d5ba2,
+        0x02e5b9c5,
+        0x83260376, 0x6295cfa9, 0x11c81968,
+        0x4e734a41,
+        0xb3472dca, 0x7b14a94a, 0x1b510052,
+        0x9a532915,
+        0xd60f573f, 0xbc9bc6e4, 0x2b60a476,
+        0x81e67400,
+        0x08ba6fb5, 0x571be91f, 0xf296ec6b,
+        0x2a0dd915,
+        0xb6636521, 0xe7b9f9b6, 0xff34052e,
+        0xc5855664,
+        0x53b02d5d, 0xa99f8fa1, 0x08ba4799,
+        0x6e85076a,
+        0x4b7a70e9, 0xb5b32944, 0xdb75092e,
+        0xc4192623,
+        0xad6ea6b0, 0x49a7df7d, 0x9cee60b8,
+        0x8fedb266,
+        0xecaa8c71, 0x699a17ff, 0x5664526c,
+        0xc2b19ee1,
+        0x193602a5, 0x75094c29, 0xa0591340,
+        0xe4183a3e,
+        0x3f54989a, 0x5b429d65, 0x6b8fe4d6,
+        0x99f73fd6,
+        0xa1d29c07, 0xefe830f5, 0x4d2d38e6,
+        0xf0255dc1,
+        0x4cdd2086, 0x8470eb26, 0x6382e9c6,
+        0x021ecc5e,
+        0x09686b3f, 0x3ebaefc9, 0x3c971814,
+        0x6b6a70a1,
+        0x687f3584, 0x52a0e286, 0xb79c5305,
+        0xaa500737,
+        0x3e07841c, 0x7fdeae5c, 0x8e7d44ec,
+        0x5716f2b8,
+        0xb03ada37, 0xf0500c0d, 0xf01c1f04,
+        0x0200b3ff,
+        0xae0cf51a, 0x3cb574b2, 0x25837a58,
+        0xdc0921bd,
+        0xd19113f9, 0x7ca92ff6, 0x94324773,
+        0x22f54701,
+        0x3ae5e581, 0x37c2dadc, 0xc8b57634,
+        0x9af3dda7,
+        0xa9446146, 0x0fd0030e, 0xecc8c73e,
+        0xa4751e41,
+        0xe238cd99, 0x3bea0e2f, 0x3280bba1,
+        0x183eb331,
+        0x4e548b38, 0x4f6db908, 0x6f420d03,
+        0xf60a04bf,
+        0x2cb81290, 0x24977c79, 0x5679b072,
+        0xbcaf89af,
+        0xde9a771f, 0xd9930810, 0xb38bae12,
+        0xdccf3f2e,
+        0x5512721f, 0x2e6b7124, 0x501adde6,
+        0x9f84cd87,
+        0x7a584718, 0x7408da17, 0xbc9f9abc,
+        0xe94b7d8c,
+        0xec7aec3a, 0xdb851dfa, 0x63094366,
+        0xc464c3d2,
+        0xef1c1847, 0x3215d908, 0xdd433b37,
+        0x24c2ba16,
+        0x12a14d43, 0x2a65c451, 0x50940002,
+        0x133ae4dd,
+        0x71dff89e, 0x10314e55, 0x81ac77d6,
+        0x5f11199b,
+        0x043556f1, 0xd7a3c76b, 0x3c11183b,
+        0x5924a509,
+        0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c,
+        0x1e153c6e,
+        0x86e34570, 0xeae96fb1, 0x860e5e0a,
+        0x5a3e2ab3,
+        0x771fe71c, 0x4e3d06fa, 0x2965dcb9,
+        0x99e71d0f,
+        0x803e89d6, 0x5266c825, 0x2e4cc978,
+        0x9c10b36a,
+        0xc6150eba, 0x94e2ea78, 0xa5fc3c53,
+        0x1e0a2df4,
+        0xf2f74ea7, 0x361d2b3d, 0x1939260f,
+        0x19c27960,
+        0x5223a708, 0xf71312b6, 0xebadfe6e,
+        0xeac31f66,
+        0xe3bc4595, 0xa67bc883, 0xb17f37d1,
+        0x018cff28,
+        0xc332ddef, 0xbe6c5aa5, 0x65582185,
+        0x68ab9802,
+        0xeecea50f, 0xdb2f953b, 0x2aef7dad,
+        0x5b6e2f84,
+        0x1521b628, 0x29076170, 0xecdd4775,
+        0x619f1510,
+        0x13cca830, 0xeb61bd96, 0x0334fe1e,
+        0xaa0363cf,
+        0xb5735c90, 0x4c70a239, 0xd59e9e0b,
+        0xcbaade14,
+        0xeecc86bc, 0x60622ca7, 0x9cab5cab,
+        0xb2f3846e,
+        0x648b1eaf, 0x19bdf0ca, 0xa02369b9,
+        0x655abb50,
+        0x40685a32, 0x3c2ab4b3, 0x319ee9d5,
+        0xc021b8f7,
+        0x9b540b19, 0x875fa099, 0x95f7997e,
+        0x623d7da8,
+        0xf837889a, 0x97e32d77, 0x11ed935f,
+        0x16681281,
+        0x0e358829, 0xc7e61fd6, 0x96dedfa1,
+        0x7858ba99,
+        0x57f584a5, 0x1b227263, 0x9b83c3ff,
+        0x1ac24696,
+        0xcdb30aeb, 0x532e3054, 0x8fd948e4,
+        0x6dbc3128,
+        0x58ebf2ef, 0x34c6ffea, 0xfe28ed61,
+        0xee7c3c73,
+        0x5d4a14d9, 0xe864b7e3, 0x42105d14,
+        0x203e13e0,
+        0x45eee2b6, 0xa3aaabea, 0xdb6c4f15,
+        0xfacb4fd0,
+        0xc742f442, 0xef6abbb5, 0x654f3b1d,
+        0x41cd2105,
+        0xd81e799e, 0x86854dc7, 0xe44b476a,
+        0x3d816250,
+        0xcf62a1f2, 0x5b8d2646, 0xfc8883a0,
+        0xc1c7b6a3,
+        0x7f1524c3, 0x69cb7492, 0x47848a0b,
+        0x5692b285,
+        0x095bbf00, 0xad19489d, 0x1462b174,
+        0x23820e00,
+        0x58428d2a, 0x0c55f5ea, 0x1dadf43e,
+        0x233f7061,
+        0x3372f092, 0x8d937e41, 0xd65fecf1,
+        0x6c223bdb,
+        0x7cde3759, 0xcbee7460, 0x4085f2a7,
+        0xce77326e,
+        0xa6078084, 0x19f8509e, 0xe8efd855,
+        0x61d99735,
+        0xa969a7aa, 0xc50c06c2, 0x5a04abfc,
+        0x800bcadc,
+        0x9e447a2e, 0xc3453484, 0xfdd56705,
+        0x0e1e9ec9,
+        0xdb73dbd3, 0x105588cd, 0x675fda79,
+        0xe3674340,
+        0xc5c43465, 0x713e38d8, 0x3d28f89e,
+        0xf16dff20,
+        0x153e21e7, 0x8fb03d4a, 0xe6e39f2b,
+        0xdb83adf7,
+        0xe93d5a68, 0x948140f7, 0xf64c261c,
+        0x94692934,
+        0x411520f7, 0x7602d4f7, 0xbcf46b2e,
+        0xd4a20068,
+        0xd4082471, 0x3320f46a, 0x43b7d4b7,
+        0x500061af,
+        0x1e39f62e, 0x97244546, 0x14214f74,
+        0xbf8b8840,
+        0x4d95fc1d, 0x96b591af, 0x70f4ddd3,
+        0x66a02f45,
+        0xbfbc09ec, 0x03bd9785, 0x7fac6dd0,
+        0x31cb8504,
+        0x96eb27b3, 0x55fd3941, 0xda2547e6,
+        0xabca0a9a,
+        0x28507825, 0x530429f4, 0x0a2c86da,
+        0xe9b66dfb,
+        0x68dc1462, 0xd7486900, 0x680ec0a4,
+        0x27a18dee,
+        0x4f3ffea2, 0xe887ad8c, 0xb58ce006,
+        0x7af4d6b6,
+        0xaace1e7c, 0xd3375fec, 0xce78a399,
+        0x406b2a42,
+        0x20fe9e35, 0xd9f385b9, 0xee39d7ab,
+        0x3b124e8b,
+        0x1dc9faf7, 0x4b6d1856, 0x26a36631,
+        0xeae397b2,
+        0x3a6efa74, 0xdd5b4332, 0x6841e7f7,
+        0xca7820fb,
+        0xfb0af54e, 0xd8feb397, 0x454056ac,
+        0xba489527,
+        0x55533a3a, 0x20838d87, 0xfe6ba9b7,
+        0xd096954b,
+        0x55a867bc, 0xa1159a58, 0xcca92963,
+        0x99e1db33,
+        0xa62a4a56, 0x3f3125f9, 0x5ef47e1c,
+        0x9029317c,
+        0xfdf8e802, 0x04272f70, 0x80bb155c,
+        0x05282ce3,
+        0x95c11548, 0xe4c66d22, 0x48c1133f,
+        0xc70f86dc,
+        0x07f9c9ee, 0x41041f0f, 0x404779a4,
+        0x5d886e17,
+        0x325f51eb, 0xd59bc0d1, 0xf2bcc18f,
+        0x41113564,
+        0x257b7834, 0x602a9c60, 0xdff8e8a3,
+        0x1f636c1b,
+        0x0e12b4c2, 0x02e1329e, 0xaf664fd1,
+        0xcad18115,
+        0x6b2395e0, 0x333e92e1, 0x3b240b62,
+        0xeebeb922,
+        0x85b2a20e, 0xe6ba0d99, 0xde720c8c,
+        0x2da2f728,
+        0xd0127845, 0x95b794fd, 0x647d0862,
+        0xe7ccf5f0,
+        0x5449a36f, 0x877d48fa, 0xc39dfd27,
+        0xf33e8d1e,
+        0x0a476341, 0x992eff74, 0x3a6f6eab,
+        0xf4f8fd37,
+        0xa812dc60, 0xa1ebddf8, 0x991be14c,
+        0xdb6e6b0d,
+        0xc67b5510, 0x6d672c37, 0x2765d43b,
+        0xdcd0e804,
+        0xf1290dc7, 0xcc00ffa3, 0xb5390f92,
+        0x690fed0b,
+        0x667b9ffb, 0xcedb7d9c, 0xa091cf0b,
+        0xd9155ea3,
+        0xbb132f88, 0x515bad24, 0x7b9479bf,
+        0x763bd6eb,
+        0x37392eb3, 0xcc115979, 0x8026e297,
+        0xf42e312d,
+        0x6842ada7, 0xc66a2b3b, 0x12754ccc,
+        0x782ef11c,
+        0x6a124237, 0xb79251e7, 0x06a1bbe6,
+        0x4bfb6350,
+        0x1a6b1018, 0x11caedfa, 0x3d25bdd8,
+        0xe2e1c3c9,
+        0x44421659, 0x0a121386, 0xd90cec6e,
+        0xd5abea2a,
+        0x64af674e, 0xda86a85f, 0xbebfe988,
+        0x64e4c3fe,
+        0x9dbc8057, 0xf0f7c086, 0x60787bf8,
+        0x6003604d,
+        0xd1fd8346, 0xf6381fb0, 0x7745ae04,
+        0xd736fccc,
+        0x83426b33, 0xf01eab71, 0xb0804187,
+        0x3c005e5f,
+        0x77a057be, 0xbde8ae24, 0x55464299,
+        0xbf582e61,
+        0x4e58f48f, 0xf2ddfda2, 0xf474ef38,
+        0x8789bdc2,
+        0x5366f9c3, 0xc8b38e74, 0xb475f255,
+        0x46fcd9b9,
+        0x7aeb2661, 0x8b1ddf84, 0x846a0e79,
+        0x915f95e2,
+        0x466e598e, 0x20b45770, 0x8cd55591,
+        0xc902de4c,
+        0xb90bace1, 0xbb8205d0, 0x11a86248,
+        0x7574a99e,
+        0xb77f19b6, 0xe0a9dc09, 0x662d09a1,
+        0xc4324633,
+        0xe85a1f02, 0x09f0be8c, 0x4a99a025,
+        0x1d6efe10,
+        0x1ab93d1d, 0x0ba5a4df, 0xa186f20f,
+        0x2868f169,
+        0xdcb7da83, 0x573906fe, 0xa1e2ce9b,
+        0x4fcd7f52,
+        0x50115e01, 0xa70683fa, 0xa002b5c4,
+        0x0de6d027,
+        0x9af88c27, 0x773f8641, 0xc3604c06,
+        0x61a806b5,
+        0xf0177a28, 0xc0f586e0, 0x006058aa,
+        0x30dc7d62,
+        0x11e69ed7, 0x2338ea63, 0x53c2dd94,
+        0xc2c21634,
+        0xbbcbee56, 0x90bcb6de, 0xebfc7da1,
+        0xce591d76,
+        0x6f05e409, 0x4b7c0188, 0x39720a3d,
+        0x7c927c24,
+        0x86e3725f, 0x724d9db9, 0x1ac15bb4,
+        0xd39eb8fc,
+        0xed545578, 0x08fca5b5, 0xd83d7cd3,
+        0x4dad0fc4,
+        0x1e50ef5e, 0xb161e6f8, 0xa28514d9,
+        0x6c51133c,
+        0x6fd5c7e7, 0x56e14ec4, 0x362abfce,
+        0xddc6c837,
+        0xd79a3234, 0x92638212, 0x670efa8e,
+        0x406000e0,
+        0x3a39ce37, 0xd3faf5cf, 0xabc27737,
+        0x5ac52d1b,
+        0x5cb0679e, 0x4fa33742, 0xd3822740,
+        0x99bc9bbe,
+        0xd5118e9d, 0xbf0f7315, 0xd62d1c7e,
+        0xc700c47b,
+        0xb78c1b6b, 0x21a19045, 0xb26eb1be,
+        0x6a366eb4,
+        0x5748ab2f, 0xbc946e79, 0xc6a376d2,
+        0x6549c2c8,
+        0x530ff8ee, 0x468dde7d, 0xd5730a1d,
+        0x4cd04dc6,
+        0x2939bbdb, 0xa9ba4650, 0xac9526e8,
+        0xbe5ee304,
+        0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2,
+        0x9a86ee22,
+        0xc089c2b8, 0x43242ef6, 0xa51e03aa,
+        0x9cf2d0a4,
+        0x83c061ba, 0x9be96a4d, 0x8fe51550,
+        0xba645bd6,
+        0x2826a2f9, 0xa73a3ae1, 0x4ba99586,
+        0xef5562e9,
+        0xc72fefd3, 0xf752f7da, 0x3f046f69,
+        0x77fa0a59,
+        0x80e4a915, 0x87b08601, 0x9b09e6ad,
+        0x3b3ee593,
+        0xe990fd5a, 0x9e34d797, 0x2cf0b7d9,
+        0x022b8b51,
+        0x96d5ac3a, 0x017da67d, 0xd1cf3ed6,
+        0x7c7d2d28,
+        0x1f9f25cf, 0xadf2b89b, 0x5ad6b472,
+        0x5a88f54c,
+        0xe029ac71, 0xe019a5e6, 0x47b0acfd,
+        0xed93fa9b,
+        0xe8d3c48d, 0x283b57cc, 0xf8d56629,
+        0x79132e28,
+        0x785f0191, 0xed756055, 0xf7960e44,
+        0xe3d35e8c,
+        0x15056dd4, 0x88f46dba, 0x03a16125,
+        0x0564f0bd,
+        0xc3eb9e15, 0x3c9057a2, 0x97271aec,
+        0xa93a072a,
+        0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb,
+        0x26dcf319,
+        0x7533d928, 0xb155fdf5, 0x03563482,
+        0x8aba3cbb,
+        0x28517711, 0xc20ad9f8, 0xabcc5167,
+        0xccad925f,
+        0x4de81751, 0x3830dc8e, 0x379d5862,
+        0x9320f991,
+        0xea7a90c2, 0xfb3e7bce, 0x5121ce64,
+        0x774fbe32,
+        0xa8b6e37e, 0xc3293d46, 0x48de5369,
+        0x6413e680,
+        0xa2ae0810, 0xdd6db224, 0x69852dfd,
+        0x09072166,
+        0xb39a460a, 0x6445c0dd, 0x586cdecf,
+        0x1c20c8ae,
+        0x5bbef7dd, 0x1b588d40, 0xccd2017f,
+        0x6bb4e3bb,
+        0xdda26a7e, 0x3a59ff45, 0x3e350a44,
+        0xbcb4cdd5,
+        0x72eacea8, 0xfa6484bb, 0x8d6612ae,
+        0xbf3c6f47,
+        0xd29be463, 0x542f5d9e, 0xaec2771b,
+        0xf64e6370,
+        0x740e0d8d, 0xe75b1357, 0xf8721671,
+        0xaf537d5d,
+        0x4040cb08, 0x4eb4e2cc, 0x34d2466a,
+        0x0115af84,
+        0xe1b00428, 0x95983a1d, 0x06b89fb4,
+        0xce6ea048,
+        0x6f3f3b82, 0x3520ab82, 0x011a1d4b,
+        0x277227f8,
+        0x611560b1, 0xe7933fdc, 0xbb3a792b,
+        0x344525bd,
+        0xa08839e1, 0x51ce794b, 0x2f32c9b7,
+        0xa01fbac9,
+        0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3,
+        0xa1e8aac7,
+        0x1a908749, 0xd44fbd9a, 0xd0dadecb,
+        0xd50ada38,
+        0x0339c32a, 0xc6913667, 0x8df9317c,
+        0xe0b12b4f,
+        0xf79e59b7, 0x43f5bb3a, 0xf2d519ff,
+        0x27d9459c,
+        0xbf97222c, 0x15e6fc2a, 0x0f91fc71,
+        0x9b941525,
+        0xfae59361, 0xceb69ceb, 0xc2a86459,
+        0x12baa8d1,
+        0xb6c1075e, 0xe3056a0c, 0x10d25065,
+        0xcb03a442,
+        0xe0ec6e0e, 0x1698db3b, 0x4c98a0be,
+        0x3278e964,
+        0x9f1f9532, 0xe0d392df, 0xd3a0342b,
+        0x8971f21e,
+        0x1b0a7441, 0x4ba3348c, 0xc5be7120,
+        0xc37632d8,
+        0xdf359f8d, 0x9b992f2e, 0xe60b6f47,
+        0x0fe3f11d,
+        0xe54cda54, 0x1edad891, 0xce6279cf,
+        0xcd3e7e6f,
+        0x1618b166, 0xfd2c1d05, 0x848fd2c5,
+        0xf6fb2299,
+        0xf523f357, 0xa6327623, 0x93a83531,
+        0x56cccd02,
+        0xacf08162, 0x5a75ebb5, 0x6e163697,
+        0x88d273cc,
+        0xde966292, 0x81b949d0, 0x4c50901b,
+        0x71c65614,
+        0xe6c6c7bd, 0x327a140a, 0x45e1d006,
+        0xc3f27b9a,
+        0xc9aa53fd, 0x62a80f00, 0xbb25bfe2,
+        0x35bdd2f6,
+        0x71126905, 0xb2040222, 0xb6cbcf7c,
+        0xcd769c2b,
+        0x53113ec0, 0x1640e3d3, 0x38abbd60,
+        0x2547adf0,
+        0xba38209c, 0xf746ce76, 0x77afa1c5,
+        0x20756060,
+        0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0,
+        0x4cf9aa7e,
+        0x1948c25c, 0x02fb8a8c, 0x01c36ae4,
+        0xd6ebe1f9,
+        0x90d4f869, 0xa65cdea0, 0x3f09252d,
+        0xc208e69f,
+        0xb74e6132, 0xce77e25b, 0x578fdfe3,
+        0x3ac372e6,
+      ]
+
+      d_base = key.bytes.slice(0, (16 + 2) * 4)
+      d = d_base.dup
+
+      (16 + 2).times do |i|
+        ri = d.shift
+        d = d_base.dup if d.empty?
+
+        ri <<= 8
+        ri |= d.shift
+        d = d_base.dup if d.empty?
+
+        ri <<= 8
+        ri |= d.shift
+        d = d_base.dup if d.empty?
+
+        ri <<= 8
+        ri |= d.shift
+        d = d_base.dup if d.empty?
+
+        @p[i] ^= ri
+      end
+
+      l, r = [0, 0]
+      0.step(16 + 2 - 1, 2) do |i|
+        l, r = Common::encrypt(l, r, self)
+        @p[i] = l
+        @p[i+1] = r
+      end
+      0.step(4 * 256 - 1, 2) do |i|
+        l, r = Common::encrypt(l, r, self)
+        @s[i] = l
+        @s[i+1] = r
+      end
+      @p.freeze
+      @s.freeze
+    end
+  end
+end
diff --git a/plugin/world/blowfish_ecb/test/cipher_test.rb b/plugin/world/blowfish_ecb/test/cipher_test.rb
new file mode 100644
index 00000000..be3b62b6
--- /dev/null
+++ b/plugin/world/blowfish_ecb/test/cipher_test.rb
@@ -0,0 +1,11 @@
+require 'test/unit'
+require 'blowfish_ecb'
+
+class CipherTest < Test::Unit::TestCase
+  def test_identity
+    cipher = Blowfish::ECB::Cipher.new("cipher_test")
+    ["hogefugahige", "1234567890", (1..255).to_a.pack("C*"), "", "1"].each do |data|
+      assert_equal(data, cipher.decrypt(cipher.encrypt(data)), "Failed at #{data}")
+    end
+  end
+end
\ No newline at end of file
diff --git a/plugin/world/blowfish_ecb/test/key_test.rb b/plugin/world/blowfish_ecb/test/key_test.rb
new file mode 100644
index 00000000..a43c311c
--- /dev/null
+++ b/plugin/world/blowfish_ecb/test/key_test.rb
@@ -0,0 +1,68 @@
+require 'test/unit'
+require 'blowfish_ecb'
+require 'pp'
+
+# Test cases taken from OpenSSL's Blowfish implementation
+# https://github.com/openssl/openssl/blob/master/test/bftest.c
+class KeyTest < Test::Unit::TestCase
+  def test_initialize
+    key = Blowfish::ECB::Key.new("foobar")
+    assert_not_nil(key)
+  end
+
+  def test_set_key
+    key = [0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87,
+        0x78, 0x69, 0x5a, 0x4b, 0x3c, 0x2d, 0x1e, 0x0f,
+        0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
+        0x88
+    ]
+    data = [0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10].pack("C*")
+    expected = [
+      [0xF9, 0xAD, 0x59, 0x7C, 0x49, 0xDB, 0x00, 0x5E],
+      [0xE9, 0x1D, 0x21, 0xC1, 0xD9, 0x61, 0xA6, 0xD6],
+      [0xE9, 0xC2, 0xB7, 0x0A, 0x1B, 0xC6, 0x5C, 0xF3],
+      [0xBE, 0x1E, 0x63, 0x94, 0x08, 0x64, 0x0F, 0x05],
+      [0xB3, 0x9E, 0x44, 0x48, 0x1B, 0xDB, 0x1E, 0x6E],
+      [0x94, 0x57, 0xAA, 0x83, 0xB1, 0x92, 0x8C, 0x0D],
+      [0x8B, 0xB7, 0x70, 0x32, 0xF9, 0x60, 0x62, 0x9D],
+      [0xE8, 0x7A, 0x24, 0x4E, 0x2C, 0xC8, 0x5E, 0x82],
+      [0x15, 0x75, 0x0E, 0x7A, 0x4F, 0x4E, 0xC5, 0x77],
+      [0x12, 0x2B, 0xA7, 0x0B, 0x3A, 0xB6, 0x4A, 0xE0],
+      [0x3A, 0x83, 0x3C, 0x9A, 0xFF, 0xC5, 0x37, 0xF6],
+      [0x94, 0x09, 0xDA, 0x87, 0xA9, 0x0F, 0x6B, 0xF2],
+      [0x88, 0x4F, 0x80, 0x62, 0x50, 0x60, 0xB8, 0xB4],
+      [0x1F, 0x85, 0x03, 0x1C, 0x19, 0xE1, 0x19, 0x68],
+      [0x79, 0xD9, 0x37, 0x3A, 0x71, 0x4C, 0xA3, 0x4F],
+      [0x93, 0x14, 0x28, 0x87, 0xEE, 0x3B, 0xE1, 0x5C],
+      [0x03, 0x42, 0x9E, 0x83, 0x8C, 0xE2, 0xD1, 0x4B],
+      [0xA4, 0x29, 0x9E, 0x27, 0x46, 0x9F, 0xF6, 0x7B],
+      [0xAF, 0xD5, 0xAE, 0xD1, 0xC1, 0xBC, 0x96, 0xA8],
+      [0x10, 0x85, 0x1C, 0x0E, 0x38, 0x58, 0xDA, 0x9F],
+      [0xE6, 0xF5, 0x1E, 0xD7, 0x9B, 0x9D, 0xB2, 0x1F],
+      [0x64, 0xA6, 0xE1, 0x4A, 0xFD, 0x36, 0xB4, 0x6F],
+      [0x80, 0xC7, 0xD7, 0xD4, 0x5A, 0x54, 0x79, 0xAD],
+      [0x05, 0x04, 0x4B, 0x62, 0xFA, 0x52, 0xD0, 0x80],
+    ]
+
+    (0...24).each do |i|
+      bf_key = Blowfish::ECB::Key.new(key[0,i+1].pack("C*"))
+      enc = Blowfish::ECB.encrypt(data, bf_key)
+      assert_equal(expected[i].pack("C*"), enc, "Failed at case #{i}")
+      dec = Blowfish::ECB.decrypt(enc, bf_key)
+      assert_equal(data, dec, "Failed at case #{i}")
+    end
+  end
+
+  def test_raw
+    cases = [
+        {key: "abcdefghijklmnopqrstuvwxyz", data: [0x424c4f57, 0x46495348], expected: [0x324ed0fe, 0xf413a203]},
+        {key: "Who is John Galt?", data: [0xfedcba98, 0x76543210], expected: [0xcc91732b, 0x8022f684]}
+    ]
+
+    cases.each do |c|
+      bf_key = Blowfish::ECB::Key.new(c[:key])
+      l, r = Blowfish::ECB::Common.encrypt(c[:data][0], c[:data][1], bf_key)
+      assert_equal(c[:expected], [l, r])
+    end
+  end
+end
\ No newline at end of file
diff --git a/plugin/world/blowfish_ecb/test/run_test.rb b/plugin/world/blowfish_ecb/test/run_test.rb
new file mode 100644
index 00000000..29c6aafc
--- /dev/null
+++ b/plugin/world/blowfish_ecb/test/run_test.rb
@@ -0,0 +1,4 @@
+require 'test/unit'
+
+$LOAD_PATH.unshift(File.expand_path(File.join(__dir__, '..')))
+exit Test::Unit::AutoRunner.run(true, __dir__)
\ No newline at end of file
diff --git a/plugin/world/keep.rb b/plugin/world/keep.rb
index c4ae7d3b..5450820f 100644
--- a/plugin/world/keep.rb
+++ b/plugin/world/keep.rb
@@ -6,6 +6,7 @@ require 'fileutils'
 require 'openssl'
 require 'securerandom'
 require 'json'
+require_relative 'blowfish_ecb/blowfish_ecb'
 
 =begin rdoc
 アカウントデータの永続化を行うユーティリティ。
@@ -122,17 +123,12 @@ module Plugin::World
       account_data end
 
     def encrypt(str)
-      cipher = OpenSSL::Cipher.new('bf-ecb').encrypt
-      cipher.key_len = ACCOUNT_CRYPT_KEY_LEN
-      cipher.key = key
-      cipher.update(str) << cipher.final end
+      cipher = Blowfish::ECB::Cipher.new(key)
+      cipher.encrypt(str) end
 
     def decrypt(binary_data)
-      cipher = OpenSSL::Cipher.new('bf-ecb').decrypt
-      cipher.key = key
-      str = cipher.update(binary_data) << cipher.final
-      str.force_encoding(Encoding::UTF_8)
-      str end
+      cipher = Blowfish::ECB::Cipher.new(key)
+      cipher.decrypt(binary_data).force_encoding(Encoding::UTF_8) end
 
     private