package aes
import (
)
type CTR struct {
b Block
ivlo, ivhi uint64
offset uint64
}
func ( *Block, []byte) *CTR {
:= newCTR(, )
return &
}
func ( *Block, []byte) CTR {
if len() != BlockSize {
panic("bad IV length")
}
return CTR{
b: *,
ivlo: byteorder.BEUint64([8:16]),
ivhi: byteorder.BEUint64([0:8]),
offset: 0,
}
}
func ( *CTR) (, []byte) {
.XORKeyStreamAt(, , .offset)
var uint64
.offset, = bits.Add64(.offset, uint64(len()), 0)
if != 0 {
panic("crypto/aes: counter overflow")
}
}
func ( *CTR) {
if := .offset % BlockSize; != 0 {
var uint64
.offset, = bits.Add64(.offset, BlockSize-, 0)
if != 0 {
panic("crypto/aes: counter overflow")
}
}
}
func ( *CTR) (, []byte, uint64) {
if len() < len() {
panic("crypto/aes: len(dst) < len(src)")
}
= [:len()]
if alias.InexactOverlap(, ) {
panic("crypto/aes: invalid buffer overlap")
}
fips140.RecordApproved()
, := add128(.ivlo, .ivhi, /BlockSize)
if := % BlockSize; != 0 {
var , [BlockSize]byte
copy([:], )
ctrBlocks1(&.b, &, &, , )
:= copy(, [:])
= [:]
= [:]
, = add128(, , 1)
}
for len() >= 8*BlockSize {
ctrBlocks8(&.b, (*[8 * BlockSize]byte)(), (*[8 * BlockSize]byte)(), , )
= [8*BlockSize:]
= [8*BlockSize:]
, = add128(, , 8)
}
if len() >= 4*BlockSize {
ctrBlocks4(&.b, (*[4 * BlockSize]byte)(), (*[4 * BlockSize]byte)(), , )
= [4*BlockSize:]
= [4*BlockSize:]
, = add128(, , 4)
}
if len() >= 2*BlockSize {
ctrBlocks2(&.b, (*[2 * BlockSize]byte)(), (*[2 * BlockSize]byte)(), , )
= [2*BlockSize:]
= [2*BlockSize:]
, = add128(, , 2)
}
if len() >= 1*BlockSize {
ctrBlocks1(&.b, (*[1 * BlockSize]byte)(), (*[1 * BlockSize]byte)(), , )
= [1*BlockSize:]
= [1*BlockSize:]
, = add128(, , 1)
}
if len() != 0 {
var , [BlockSize]byte
copy([:], )
ctrBlocks1(&.b, &, &, , )
copy(, [:])
}
}
func ( *Block, , []byte, , uint64) {
:= make([]byte, len(), 8*BlockSize)
for := 0; < len(); += BlockSize {
byteorder.BEPutUint64([:], )
byteorder.BEPutUint64([+8:], )
, = add128(, , 1)
encryptBlock(, [:], [:])
}
subtle.XORBytes(, , )
copy(, )
}
func (, uint64, uint64) (uint64, uint64) {
, := bits.Add64(, , 0)
, _ = bits.Add64(, 0, )
return ,
}