// Copyright 2010 The Go Authors. All rights reserved.// Use of this source code is governed by a BSD-style// license that can be found in the LICENSE file.package blowfish// getNextWord returns the next big-endian uint32 value from the byte slice// at the given position in a circular manner, updating the position.func getNextWord( []byte, *int) uint32 {varuint32 := *for := 0; < 4; ++ { = <<8 | uint32([]) ++if >= len() { = 0 } } * = return}// ExpandKey performs a key expansion on the given *Cipher. Specifically, it// performs the Blowfish algorithm's key schedule which sets up the *Cipher's// pi and substitution tables for calls to Encrypt. This is used, primarily,// by the bcrypt package to reuse the Blowfish key schedule during its// set up. It's unlikely that you need to use this directly.func ( []byte, *Cipher) { := 0for := 0; < 18; ++ {// Using inlined getNextWord for performance.varuint32for := 0; < 4; ++ { = <<8 | uint32([]) ++if >= len() { = 0 } } .p[] ^= }var , uint32for := 0; < 18; += 2 { , = encryptBlock(, , ) .p[], .p[+1] = , }for := 0; < 256; += 2 { , = encryptBlock(, , ) .s0[], .s0[+1] = , }for := 0; < 256; += 2 { , = encryptBlock(, , ) .s1[], .s1[+1] = , }for := 0; < 256; += 2 { , = encryptBlock(, , ) .s2[], .s2[+1] = , }for := 0; < 256; += 2 { , = encryptBlock(, , ) .s3[], .s3[+1] = , }}// This is similar to ExpandKey, but folds the salt during the key// schedule. While ExpandKey is essentially expandKeyWithSalt with an all-zero// salt passed in, reusing ExpandKey turns out to be a place of inefficiency// and specializing it here is useful.func expandKeyWithSalt( []byte, []byte, *Cipher) { := 0for := 0; < 18; ++ { .p[] ^= getNextWord(, &) } = 0var , uint32for := 0; < 18; += 2 { ^= getNextWord(, &) ^= getNextWord(, &) , = encryptBlock(, , ) .p[], .p[+1] = , }for := 0; < 256; += 2 { ^= getNextWord(, &) ^= getNextWord(, &) , = encryptBlock(, , ) .s0[], .s0[+1] = , }for := 0; < 256; += 2 { ^= getNextWord(, &) ^= getNextWord(, &) , = encryptBlock(, , ) .s1[], .s1[+1] = , }for := 0; < 256; += 2 { ^= getNextWord(, &) ^= getNextWord(, &) , = encryptBlock(, , ) .s2[], .s2[+1] = , }for := 0; < 256; += 2 { ^= getNextWord(, &) ^= getNextWord(, &) , = encryptBlock(, , ) .s3[], .s3[+1] = , }}func encryptBlock(, uint32, *Cipher) (uint32, uint32) { , := , ^= .p[0] ^= ((.s0[byte(>>24)] + .s1[byte(>>16)]) ^ .s2[byte(>>8)]) + .s3[byte()] ^ .p[1] ^= ((.s0[byte(>>24)] + .s1[byte(>>16)]) ^ .s2[byte(>>8)]) + .s3[byte()] ^ .p[2] ^= ((.s0[byte(>>24)] + .s1[byte(>>16)]) ^ .s2[byte(>>8)]) + .s3[byte()] ^ .p[3] ^= ((.s0[byte(>>24)] + .s1[byte(>>16)]) ^ .s2[byte(>>8)]) + .s3[byte()] ^ .p[4] ^= ((.s0[byte(>>24)] + .s1[byte(>>16)]) ^ .s2[byte(>>8)]) + .s3[byte()] ^ .p[5] ^= ((.s0[byte(>>24)] + .s1[byte(>>16)]) ^ .s2[byte(>>8)]) + .s3[byte()] ^ .p[6] ^= ((.s0[byte(>>24)] + .s1[byte(>>16)]) ^ .s2[byte(>>8)]) + .s3[byte()] ^ .p[7] ^= ((.s0[byte(>>24)] + .s1[byte(>>16)]) ^ .s2[byte(>>8)]) + .s3[byte()] ^ .p[8] ^= ((.s0[byte(>>24)] + .s1[byte(>>16)]) ^ .s2[byte(>>8)]) + .s3[byte()] ^ .p[9] ^= ((.s0[byte(>>24)] + .s1[byte(>>16)]) ^ .s2[byte(>>8)]) + .s3[byte()] ^ .p[10] ^= ((.s0[byte(>>24)] + .s1[byte(>>16)]) ^ .s2[byte(>>8)]) + .s3[byte()] ^ .p[11] ^= ((.s0[byte(>>24)] + .s1[byte(>>16)]) ^ .s2[byte(>>8)]) + .s3[byte()] ^ .p[12] ^= ((.s0[byte(>>24)] + .s1[byte(>>16)]) ^ .s2[byte(>>8)]) + .s3[byte()] ^ .p[13] ^= ((.s0[byte(>>24)] + .s1[byte(>>16)]) ^ .s2[byte(>>8)]) + .s3[byte()] ^ .p[14] ^= ((.s0[byte(>>24)] + .s1[byte(>>16)]) ^ .s2[byte(>>8)]) + .s3[byte()] ^ .p[15] ^= ((.s0[byte(>>24)] + .s1[byte(>>16)]) ^ .s2[byte(>>8)]) + .s3[byte()] ^ .p[16] ^= .p[17]return , }func decryptBlock(, uint32, *Cipher) (uint32, uint32) { , := , ^= .p[17] ^= ((.s0[byte(>>24)] + .s1[byte(>>16)]) ^ .s2[byte(>>8)]) + .s3[byte()] ^ .p[16] ^= ((.s0[byte(>>24)] + .s1[byte(>>16)]) ^ .s2[byte(>>8)]) + .s3[byte()] ^ .p[15] ^= ((.s0[byte(>>24)] + .s1[byte(>>16)]) ^ .s2[byte(>>8)]) + .s3[byte()] ^ .p[14] ^= ((.s0[byte(>>24)] + .s1[byte(>>16)]) ^ .s2[byte(>>8)]) + .s3[byte()] ^ .p[13] ^= ((.s0[byte(>>24)] + .s1[byte(>>16)]) ^ .s2[byte(>>8)]) + .s3[byte()] ^ .p[12] ^= ((.s0[byte(>>24)] + .s1[byte(>>16)]) ^ .s2[byte(>>8)]) + .s3[byte()] ^ .p[11] ^= ((.s0[byte(>>24)] + .s1[byte(>>16)]) ^ .s2[byte(>>8)]) + .s3[byte()] ^ .p[10] ^= ((.s0[byte(>>24)] + .s1[byte(>>16)]) ^ .s2[byte(>>8)]) + .s3[byte()] ^ .p[9] ^= ((.s0[byte(>>24)] + .s1[byte(>>16)]) ^ .s2[byte(>>8)]) + .s3[byte()] ^ .p[8] ^= ((.s0[byte(>>24)] + .s1[byte(>>16)]) ^ .s2[byte(>>8)]) + .s3[byte()] ^ .p[7] ^= ((.s0[byte(>>24)] + .s1[byte(>>16)]) ^ .s2[byte(>>8)]) + .s3[byte()] ^ .p[6] ^= ((.s0[byte(>>24)] + .s1[byte(>>16)]) ^ .s2[byte(>>8)]) + .s3[byte()] ^ .p[5] ^= ((.s0[byte(>>24)] + .s1[byte(>>16)]) ^ .s2[byte(>>8)]) + .s3[byte()] ^ .p[4] ^= ((.s0[byte(>>24)] + .s1[byte(>>16)]) ^ .s2[byte(>>8)]) + .s3[byte()] ^ .p[3] ^= ((.s0[byte(>>24)] + .s1[byte(>>16)]) ^ .s2[byte(>>8)]) + .s3[byte()] ^ .p[2] ^= ((.s0[byte(>>24)] + .s1[byte(>>16)]) ^ .s2[byte(>>8)]) + .s3[byte()] ^ .p[1] ^= .p[0]return , }
The pages are generated with Goldsv0.6.7. (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu.
PR and bug reports are welcome and can be submitted to the issue list.
Please follow @Go100and1 (reachable from the left QR code) to get the latest news of Golds.