Commit 06e5a558 authored by Paulo Flabiano Smorigo's avatar Paulo Flabiano Smorigo Committed by Lynn Boger

crypto/aes: improve performance for aes on ppc64le

Add asm implementation for AES in order to make use of VMX cryptographic
acceleration instructions for POWER8. There is a speed boost of over 10
times using those instructions:

Fixes #18076

                        old ns/op  new ns/op  delta
BenchmarkEncrypt-20     337        30.3       -91.00%
BenchmarkDecrypt-20     347        30.5a      -91.21%
BenchmarkExpand-20      1180       130        -88.98%

                        old MB/s   new MB/s   speedup
BenchmarkEncrypt-20     47.38      527.68     11.13x
BenchmarkDecrypt-20     46.05      524.45     11.38x

Change-Id: Ifa4d1b508f4803cc72dcaad97acc8495d651b019
Reviewed-on: https://go-review.googlesource.com/33587
Run-TryBot: Lynn Boger <laboger@linux.vnet.ibm.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarLynn Boger <laboger@linux.vnet.ibm.com>
parent f02dda50
This diff is collapsed.
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build !amd64,!s390x
// +build !amd64,!s390x,!ppc64le
package aes
......
// Copyright 2016 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 aes
import (
"crypto/cipher"
)
// defined in asm_ppc64le.s
//go:noescape
func setEncryptKeyAsm(key *byte, keylen int, enc *uint32) int
//go:noescape
func setDecryptKeyAsm(key *byte, keylen int, dec *uint32) int
//go:noescape
func doEncryptKeyAsm()
//go:noescape
func encryptBlockAsm(dst, src *byte, enc *uint32)
//go:noescape
func decryptBlockAsm(dst, src *byte, dec *uint32)
type aesCipherAsm struct {
aesCipher
}
func newCipher(key []byte) (cipher.Block, error) {
n := 64 // size is fixed for all and round value is stored inside it too
c := aesCipherAsm{aesCipher{make([]uint32, n), make([]uint32, n)}}
k := len(key)
ret := 0
ret += setEncryptKeyAsm(&key[0], k*8, &c.enc[0])
ret += setDecryptKeyAsm(&key[0], k*8, &c.dec[0])
if ret > 0 {
return nil, KeySizeError(k)
}
return &c, nil
}
func (c *aesCipherAsm) BlockSize() int { return BlockSize }
func (c *aesCipherAsm) Encrypt(dst, src []byte) {
if len(src) < BlockSize {
panic("crypto/aes: input not full block")
}
if len(dst) < BlockSize {
panic("crypto/aes: output not full block")
}
encryptBlockAsm(&dst[0], &src[0], &c.enc[0])
}
func (c *aesCipherAsm) Decrypt(dst, src []byte) {
if len(src) < BlockSize {
panic("crypto/aes: input not full block")
}
if len(dst) < BlockSize {
panic("crypto/aes: output not full block")
}
decryptBlockAsm(&dst[0], &src[0], &c.dec[0])
}
// expandKey is used by BenchmarkExpand to ensure that the asm implementation
// of key expansion is used for the benchmark when it is available.
func expandKey(key []byte, enc, dec []uint32) {
setEncryptKeyAsm(&key[0], len(key)*8, &enc[0])
setDecryptKeyAsm(&key[0], len(key)*8, &dec[0])
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment