github.com/chain5j/chain5j-pkg@v1.0.7/crypto/scrypt/presale.go (about) 1 package scrypt 2 3 import ( 4 "crypto/aes" 5 "crypto/cipher" 6 ) 7 8 func aesCTRXOR(key, inText, iv []byte) ([]byte, error) { 9 // AES-128 is selected due to size of encryptKey. 10 aesBlock, err := aes.NewCipher(key) 11 if err != nil { 12 return nil, err 13 } 14 stream := cipher.NewCTR(aesBlock, iv) 15 outText := make([]byte, len(inText)) 16 stream.XORKeyStream(outText, inText) 17 return outText, err 18 } 19 20 func aesCBCDecrypt(key, cipherText, iv []byte) ([]byte, error) { 21 aesBlock, err := aes.NewCipher(key) 22 if err != nil { 23 return nil, err 24 } 25 decrypter := cipher.NewCBCDecrypter(aesBlock, iv) 26 paddedPlaintext := make([]byte, len(cipherText)) 27 decrypter.CryptBlocks(paddedPlaintext, cipherText) 28 plaintext := pkcs7Unpad(paddedPlaintext) 29 if plaintext == nil { 30 return nil, ErrDecrypt 31 } 32 return plaintext, err 33 } 34 35 // From https://leanpub.com/gocrypto/read#leanpub-auto-block-cipher-modes 36 func pkcs7Unpad(in []byte) []byte { 37 if len(in) == 0 { 38 return nil 39 } 40 41 padding := in[len(in)-1] 42 if int(padding) > len(in) || padding > aes.BlockSize { 43 return nil 44 } else if padding == 0 { 45 return nil 46 } 47 48 for i := len(in) - 1; i > len(in)-int(padding)-1; i-- { 49 if in[i] != padding { 50 return nil 51 } 52 } 53 return in[:len(in)-int(padding)] 54 }