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  }