// GoGOST -- Pure Go GOST cryptographic functions library // Copyright (C) 2015-2024 Sergey Matveev // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, version 3 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . package gost28147 type CTR struct { c *Cipher n1 nv n2 nv } func (c *Cipher) NewCTR(iv []byte) *CTR { if len(iv) != BlockSize { panic("iv length is not equal to blocksize") } n1, n2 := block2nvs(iv) n2, n1 = c.xcrypt(SeqEncrypt, n1, n2) return &CTR{c, n1, n2} } func (c *CTR) XORKeyStream(dst, src []byte) { var n1t nv var n2t nv block := make([]byte, BlockSize) i := 0 var n int MainLoop: for { c.n1 += 0x01010101 // C2 c.n2 += 0x01010104 // C1 if c.n2 >= 1<<32-1 { c.n2 -= 1<<32 - 1 } n1t, n2t = c.c.xcrypt(SeqEncrypt, c.n1, c.n2) nvs2block(n1t, n2t, block) for n = 0; n < BlockSize; n++ { if i*BlockSize+n == len(src) { break MainLoop } dst[i*BlockSize+n] = src[i*BlockSize+n] ^ block[n] } i++ } }