[Golang] Go implementation of Blowfish algorithm

Source: Internet
Author: User
This is a creation in Article, where the information may have evolved or changed.

Recently due to the need for work, the implementation of a go Blowfish algorithm is required. In fact, go itself has a cryptographic algorithm library crypto, which has blowfish. But the algorithm differs from my needs in many details, resulting in a wide variety of final encryption results.

Blowfish algorithm

Blowfish is one of the symmetric cryptographic algorithms. In many scenarios, an alternative to des appears. Blowfish does not encrypt the data directly with the key we specify, but first preprocess the key and then encrypts the data with the result of the processing. The decryption process is the same.

The Blowfish algorithm contains two source keys: Pbox and sbox,pbox18 bit arrays, sbox4 256-bit arrays. The algorithm uses a lot of displacement and logical bit operations in two boxes when encrypting and decrypting. Details of the specific algorithm Baidu/Google, this article is not detailed.

Go implementation

1. Generate Pbox and Sbox

A few important variable declarations

var (    Pencs string = "!!!这是一个18位长度的串!!!"    Sencs string = "!!!这是一个1024位长度的串!!!"    Penc []uint8 = []uint8(Pencs)    Senc []uint8 = []uint8(Sencs)    Pinit []uint32 = make([]uint32, len(Penc)*7/32)    Sinit []uint32 = make([]uint32, len(Senc)*7/32)    PPP  []uint32 = make([]uint32, 18)  //p盒子    SSS0 []uint32 = make([]uint32, 256) //第一个盒子    SSS1 []uint32 = make([]uint32, 256) //第二个盒子    SSS2 []uint32 = make([]uint32, 256) //第三个盒子    SSS3 []uint32 = make([]uint32, 256) //第四个盒子)

Generate Pbox and Sbox

The source string of the 2 boxes is Pencs and Sencs, each byte is shifted to the right by a certain number of digits, resulting in an intermediate array pinit and Sinit

  func Initparam () {var poff int32 = Plen: = Len (Penc) for I, J: = 0, 0; j < Plen; F j = = plen-1 {Pinit[i] |= UInt32 (penc[j]) >> UInt32 (-poff)} else if Poff < 0 {Pi Nit[i] |= UInt32 (penc[j]) >> UInt32 (-poff) i++ Poff + = Pinit[i] |= uint32 (penc[j  ]) << UInt32 (Poff)} else {Pinit[i] |= UInt32 (penc[j]) << UInt32 (Poff)} Poff -= 7} var soff int32 = Slen: = Len (Senc) for I, J: = 0, 0; J < Slen;             J + + {if J = slen-1 {Sinit[i] |= UInt32 (senc[j]) >> UInt32 (-soff)} else if Soff < 0 {  Sinit[i] |= UInt32 (senc[j]) >> UInt32 (-soff) i++ Soff + = Sinit[i] |=        UInt32 (Senc[j]) << UInt32 (Soff)} else {Sinit[i] |= UInt32 (senc[j]) << UInt32 (Soff) } Soff-= 7}}  

2. Key preprocessing

Func Setkey (key []uint8) {ptemp: = []uint32{0, 0} stemp: = [][]uint32{sss0, SSS1, SSS2, SSS3} copy (PPP, Pinit) For I, J: = 0, 0; I < 4; i++ {copy (Stemp[i], Sinit[j:]) J + = $ Lenth: = Len (key) LL: = 0 for I, j: = UInt32 (0), uint 32 (0); I < 18;            i++ {for k: = 0; k < 4; k++ {ll%= lenth j = j<<8 | UInt32 (Key[ll]) &255 ll++} Ppp[i] ^= J} encryptkey (ptemp, 0, PPP, 0) for I: = UInt32 (0); I < 16; i + = 2 {encryptkey (PPP, I, PPP, i+2)} encryptkey (PPP, UInt32, Stemp[0], 0) for J: = (2); J < 256; J + = 2 {Encryptkey (stemp[0], UInt32 (j-2), stemp[0], UInt32 (j))} K: = 0 L: = 254 for I: = 1; I < 4;  i++ {for J: = 0, J < N, j + = 2 {Encryptkey (stemp[k], UInt32 (L), Stemp[i], UInt32 (j)) K  = i L = j}}}func Encryptkey (in []uint32, Inoff UInt32, out []uint32, Outoff UInt32) {  Left: = In[inoff] ^ ppp[0] inoff++ Right: = In[inoff] for I: = 0; I < 16; i++ {temp: = (sss0[left>>24&255] + sss1[left>>16&255] ^ sss2[left>>8&255]) + SSS3[le FT&AMP;255] i++ Right ^= temp ^ ppp[i] temp = (sss0[right>>24&255] + SSS1[RIGHT&GT;&GT;16&A  MP;255] ^ sss2[right>>8&255]) + sss3[right&255] Left ^= temp ^ ppp[i+1]} Out[outoff] = right ^ PPP[17] outoff++ Out[outoff] = left}

3. Encryption

Func Encrypt (encryptable []uint8) []uint8 {blocks: = Len (encryptable)/+ REM: = Len (encryptable)% length: = blocks * + var output []uint8 if rem > 0 {output = make ([]uint8, length+64)} else {output = Make ([]uint8, length)} for I: = 0; i < 64-rem; i++ {encryptable = append (encryptable, 0)} for I: = 0; I < Len (encryptable); i + = 8 {encryptbytes (encryptable, UInt32 (i), output, UInt32 (i))} return Output}func encryptbytes (in []uint8 , Inoff UInt32, out []uint8, Outoff UInt32) {left: = ((UInt32 (In[inoff]) &255) <<24 | (UInt32 (in[inoff+1]) &255) <<16 | (UInt32 (in[inoff+2]) &255) <<8 | (UInt32 (in[inoff+3]) & 255)) ^ Ppp[0] Right: = (UInt32 (in[inoff+4]) &255) <<24 | (UInt32 (in[inoff+5]) &255) <<16 | (UInt32 (in[inoff+6]) &255) <<8 | UInt32 (In[inoff+7]) &255 for I: = 1; I < 17; i + = 2 {right ^= (sss0[left>>24&255] + sss1[left&GT;&GT;16&AMP;255] ^ sss2[left>>8&255]) + sss3[left&255] ^ ppp[i] left ^= (sss0[right>>24& 255] + sss1[right>>16&255] ^ sss2[right>>8&255]) + sss3[right&255] ^ PPP[i+1]} right ^= PPP [Out[outoff] = Uint8 (right >> & 255) out[outoff+1] = Uint8 (right >> + & 255) Out[outo  FF+2] = uint8 (right >> 8 & 255) out[outoff+3] = Uint8 (right & 255) out[outoff+4] = Uint8 (left >>    (& 255) out[outoff+5] = Uint8 (left >> 255) out[outoff+6] = Uint8 (left >> 8 & 255) OUT[OUTOFF+7] = Uint8 (left & 255)}
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.