# BLOFSH
> [HTML Version](blofshsbr.htm)
_Added to A-Shell, August 2016_
**xcall BLOFSH, opcode(=1), impure, key**
**xcall BLOFSH, opcode(=2), impure, cleartext, ciphertext**
**xcall BLOFSH, opcode(=3), impure, ciphertext, cleartext**
BLOFSH implements the Blowfish encryption algorithm. It is used to encrypt or decrypt data in memory using a variable length key of 32 to 448 bits.
Blowfish is a symmetric-key block cipher, designed in 1993 by Bruce Schneier and made available to the world for royalty-free use. See [the Blowfish entry at Wikipedia](https://en.wikipedia.org/wiki/Blowfish_(cipher)) for more information.
**Parameters**
_opcode_ ([Num](num.htm.md)) \[in\]
1 to load the key, 2 to encrypt, 3 to decrypt
_impure_ [(BLOB](blob.htm.md), 4168) \[in/out\]
A block of 4168 bytes which must be provided to the subroutine for its use as a work area. Do not modify it between calls.
_key _[(BLOB](blob.htm.md)) \[in\]
A variable containing your encryption key. The mapped size of _key_ determines the length of the encryption key, which can be from 4 to 56 bytes—i.e. 32 to 448 bits. Note being a symmetric cipher, the same key is used for encryption and decryption. Obviously you should generate an unpredictable key and store it securely.
_cleartext_ [(BLOB](blob.htm.md)) \[in/out\]
An area containing or overlaying the clear data. For _opcode_ 2 (encrypt), this is the source; for _opcode_ 3 (decrypt), it is the destination. The size in bytes must be divisible by 4, and must match the _ciphertext_ size. You can use an overlay or an assignment to up-size your actual clear text field. For example, to encrypt a string 29 bytes long, you might map it as follows:
map1 cleartext\$,s,29
map1 cleartext,x,32,@cleartext\$
_ciphertext _[(BLOB](blob.htm.md)) \[in/out\]
An area containing or overlaying the encrypted data. Restrictions and comments given for cleartext apply here as well.
**(./images/hmtoggle_plus0.gif) Example**
MAP1 X,I,2
MAP1 BF'IMPURE,X,4168 \! internal work area
MAP1 BF'KEY \! (4 to 56 bytes, divisible by 4)
MAP2 BF'KEY(4),B,4 \! 16 bytes (128 bits)
MAP1 SECRETS
MAP2 NAME,S,36
MAP2 CODE,F,6
MAP1 CLEARTEXT,X,48,@SECRETS \! must be divisible by 8
MAP1 CIPHERTEXT,X,48 \! must be same size as CLEARTEXT
X = SRND2(0,0,\&hFFFFFFFF) \! randomize, set 32 bit range
for X = 1 to 4 \! generate 4 32-bit random values for key
BF'KEY(X) = RND2()
next X
open #1, "BLOTST.KEY", output \! save the key
? #1, BF'KEY;
close #1
xcall BLOFSH, 1, BF'IMPURE, BF'KEY \! init cipher from key
NAME = "James Bond"
CODE = 0.007
xcall BLOFSH, 2, BF'IMPURE, CLEARTEXT, CIPHERTEXT \! encrypt
open #2, "BLOTST.DAT", OUTPUT
? #2, CIPHERTEXT; \! write encrypted data to file
close #2
\! later, to decrypt...
open #1, "BLOTST.KEY", input \! retrieve the saved key
input raw #1, BF'KEY
close #1
xcall BLOFSH, 1, BF'IMPURE, BF'KEY \! re-init cipher from key
open #2, "BLOTST.DAT", input
input raw #2, CIPHERTEXT \! read encrypted data
close #2
xcall BLOFSH, 3, BF'IMPURE, CIPHERTEXT, CLEARTEXT \! decrypt
? "NAME = ";NAME;", CODE = ";CODE
end
**Comments**
When encrypting string fields, you can copy to/from the original (S format) field and the _cleartext_ / _ciphertext_ (X format) fields. But when encrypting numeric fields or structures, you must use the overlay method shown above. In all cases, you must save the entire _ciphertext_ variable, not just the number of bytes in the actual data. In the example above, the actual data is only 43 bytes but the encrypted data is 48 bytes long, i.e rounded up to the next multiple of 8 bytes.
To generate truly unpredictable keys, see [Random Number Generators](randomnumbergenerators.htm.md). To avoid saving the key, you may be able to use some fixed function based on inputs unique to the situation—file #, customer #, ppn, etc.—to produce the seed from which you then can generate and later regenerate a pseudo-random sequence.
If you are exporting your application which encrypts or contains encrypted data, you may want to check your country's regulations. The US has loosened its requirements but there are still situations where Blowfish encryption with keys longer than 56 bits may be restricted.
**See Also**
• [CRYPTO](cryptosbr.htm.md)
• [MX\_PWCRYPT](mx_pwcrypt.htm.md)