X-Git-Url: http://www.git.cypherpunks.ru/?p=gogost.git;a=blobdiff_plain;f=gost3412128%2Fcipher.go;h=cbc2b3ef81c34e66a69786c8e4bb4a85682c7294;hp=fd48d8b8f153fd70d59253b56822cf52dc696c60;hb=9009082ff15ac83ea5923042c22891b6b525bc72;hpb=1fa893a0d8d18c9662cab80ca142b1319bf4bd80 diff --git a/gost3412128/cipher.go b/gost3412128/cipher.go index fd48d8b..cbc2b3e 100644 --- a/gost3412128/cipher.go +++ b/gost3412128/cipher.go @@ -51,8 +51,9 @@ var ( 190, 229, 108, 82, 89, 166, 116, 210, 230, 244, 180, 192, 209, 102, 175, 194, 57, 75, 99, 182, } - piInv [256]byte - cBlk [32]*[BlockSize]byte + piInv [256]byte + cBlk [32][]byte + gfCache [256][256]byte ) func gf(a, b byte) (c byte) { @@ -70,61 +71,108 @@ func gf(a, b byte) (c byte) { return } -func l(blk *[BlockSize]byte, rounds int) { - var t byte - var i int - for ; rounds > 0; rounds-- { - t = blk[15] - for i = 14; i >= 0; i-- { - blk[i+1] = blk[i] - t ^= gf(blk[i], lc[i]) - } +func l(blk []byte) { + for n := 0; n < BlockSize; n++ { + t := blk[15] + t ^= gfCache[blk[0]][lc[0]] + t ^= gfCache[blk[1]][lc[1]] + t ^= gfCache[blk[2]][lc[2]] + t ^= gfCache[blk[3]][lc[3]] + t ^= gfCache[blk[4]][lc[4]] + t ^= gfCache[blk[5]][lc[5]] + t ^= gfCache[blk[6]][lc[6]] + t ^= gfCache[blk[7]][lc[7]] + t ^= gfCache[blk[8]][lc[8]] + t ^= gfCache[blk[9]][lc[9]] + t ^= gfCache[blk[10]][lc[10]] + t ^= gfCache[blk[11]][lc[11]] + t ^= gfCache[blk[12]][lc[12]] + t ^= gfCache[blk[13]][lc[13]] + t ^= gfCache[blk[14]][lc[14]] + copy(blk[1:], blk) blk[0] = t } } -func lInv(blk *[BlockSize]byte) { - var t byte - var i int +func lInv(blk []byte) { for n := 0; n < BlockSize; n++ { - t = blk[0] - for i = 0; i < 15; i++ { - blk[i] = blk[i+1] - t ^= gf(blk[i], lc[i]) - } + t := blk[0] + copy(blk, blk[1:]) + t ^= gfCache[blk[0]][lc[0]] + t ^= gfCache[blk[1]][lc[1]] + t ^= gfCache[blk[2]][lc[2]] + t ^= gfCache[blk[3]][lc[3]] + t ^= gfCache[blk[4]][lc[4]] + t ^= gfCache[blk[5]][lc[5]] + t ^= gfCache[blk[6]][lc[6]] + t ^= gfCache[blk[7]][lc[7]] + t ^= gfCache[blk[8]][lc[8]] + t ^= gfCache[blk[9]][lc[9]] + t ^= gfCache[blk[10]][lc[10]] + t ^= gfCache[blk[11]][lc[11]] + t ^= gfCache[blk[12]][lc[12]] + t ^= gfCache[blk[13]][lc[13]] + t ^= gfCache[blk[14]][lc[14]] blk[15] = t } } func init() { - piInvP := new([256]byte) + for a := 0; a < 256; a++ { + for b := 0; b < 256; b++ { + gfCache[a][b] = gf(byte(a), byte(b)) + } + } for i := 0; i < 256; i++ { - piInvP[int(pi[i])] = byte(i) + piInv[int(pi[i])] = byte(i) } - piInv = *piInvP - CP := new([32]*[BlockSize]byte) for i := 0; i < 32; i++ { - CP[i] = new([BlockSize]byte) - CP[i][15] = byte(i) + 1 - l(CP[i], 16) + cBlk[i] = make([]byte, BlockSize) + cBlk[i][15] = byte(i) + 1 + l(cBlk[i]) } - cBlk = *CP } -func s(blk *[BlockSize]byte) { - for i := 0; i < BlockSize; i++ { - blk[i] = pi[int(blk[i])] - } +func s(blk []byte) { + blk[0] = pi[int(blk[0])] + blk[1] = pi[int(blk[1])] + blk[2] = pi[int(blk[2])] + blk[3] = pi[int(blk[3])] + blk[4] = pi[int(blk[4])] + blk[5] = pi[int(blk[5])] + blk[6] = pi[int(blk[6])] + blk[7] = pi[int(blk[7])] + blk[8] = pi[int(blk[8])] + blk[9] = pi[int(blk[9])] + blk[10] = pi[int(blk[10])] + blk[11] = pi[int(blk[11])] + blk[12] = pi[int(blk[12])] + blk[13] = pi[int(blk[13])] + blk[14] = pi[int(blk[14])] + blk[15] = pi[int(blk[15])] } -func xor(dst, src1, src2 *[BlockSize]byte) { - for i := 0; i < BlockSize; i++ { - dst[i] = src1[i] ^ src2[i] - } +func xor(dst, src1, src2 []byte) { + dst[0] = src1[0] ^ src2[0] + dst[1] = src1[1] ^ src2[1] + dst[2] = src1[2] ^ src2[2] + dst[3] = src1[3] ^ src2[3] + dst[4] = src1[4] ^ src2[4] + dst[5] = src1[5] ^ src2[5] + dst[6] = src1[6] ^ src2[6] + dst[7] = src1[7] ^ src2[7] + dst[8] = src1[8] ^ src2[8] + dst[9] = src1[9] ^ src2[9] + dst[10] = src1[10] ^ src2[10] + dst[11] = src1[11] ^ src2[11] + dst[12] = src1[12] ^ src2[12] + dst[13] = src1[13] ^ src2[13] + dst[14] = src1[14] ^ src2[14] + dst[15] = src1[15] ^ src2[15] } type Cipher struct { - ks [10]*[BlockSize]byte + ks [10][]byte } func (c *Cipher) BlockSize() int { @@ -135,48 +183,47 @@ func NewCipher(key []byte) *Cipher { if len(key) != KeySize { panic("invalid key size") } - ks := new([10]*[BlockSize]byte) - kr0 := new([BlockSize]byte) - kr1 := new([BlockSize]byte) - krt := new([BlockSize]byte) - copy(kr0[:], key[:BlockSize]) - copy(kr1[:], key[BlockSize:]) - ks[0] = new([BlockSize]byte) - ks[1] = new([BlockSize]byte) - copy(ks[0][:], kr0[:]) - copy(ks[1][:], kr1[:]) + var ks [10][]byte + for i := 0; i < len(ks); i++ { + ks[i] = make([]byte, BlockSize) + } + kr0 := make([]byte, BlockSize) + kr1 := make([]byte, BlockSize) + krt := make([]byte, BlockSize) + copy(kr0, key[:BlockSize]) + copy(kr1, key[BlockSize:]) + copy(ks[0], kr0) + copy(ks[1], kr1) for i := 0; i < 4; i++ { for j := 0; j < 8; j++ { xor(krt, kr0, cBlk[8*i+j]) s(krt) - l(krt, 16) + l(krt) xor(krt, krt, kr1) - copy(kr1[:], kr0[:]) - copy(kr0[:], krt[:]) + copy(kr1, kr0) + copy(kr0, krt) } - ks[2+2*i] = new([BlockSize]byte) - copy(ks[2+2*i][:], kr0[:]) - ks[2+2*i+1] = new([BlockSize]byte) - copy(ks[2+2*i+1][:], kr1[:]) + copy(ks[2+2*i], kr0) + copy(ks[2+2*i+1], kr1) } - return &Cipher{*ks} + return &Cipher{ks} } func (c *Cipher) Encrypt(dst, src []byte) { - blk := new([BlockSize]byte) - copy(blk[:], src) + blk := make([]byte, BlockSize) + copy(blk, src) for i := 0; i < 9; i++ { xor(blk, blk, c.ks[i]) s(blk) - l(blk, 16) + l(blk) } xor(blk, blk, c.ks[9]) - copy(dst[:BlockSize], blk[:]) + copy(dst[:BlockSize], blk) } func (c *Cipher) Decrypt(dst, src []byte) { - blk := new([BlockSize]byte) - copy(blk[:], src) + blk := make([]byte, BlockSize) + copy(blk, src) var n int for i := 9; i > 0; i-- { xor(blk, blk, c.ks[i]) @@ -186,5 +233,5 @@ func (c *Cipher) Decrypt(dst, src []byte) { } } xor(blk, blk, c.ks[0]) - copy(dst[:BlockSize], blk[:]) + copy(dst[:BlockSize], blk) }