From: Sergey Matveev Date: Sun, 9 Jun 2019 10:13:58 +0000 (+0300) Subject: 34.12-2015 Magma cipher X-Git-Tag: 3.0~19 X-Git-Url: http://www.git.cypherpunks.ru/?p=gogost.git;a=commitdiff_plain;h=32e850a63da24008d8795c35369eda5e76fef7c7 34.12-2015 Magma cipher --- diff --git a/README b/README index 1597289..0c97b62 100644 --- a/README +++ b/README @@ -13,6 +13,7 @@ GOST is GOvernment STandard of Russian Federation (and Soviet Union). * VKO GOST R 34.10-2001 key agreement function (RFC 4357) * VKO GOST R 34.10-2012 key agreement function (RFC 7836) * GOST R 34.12-2015 128-bit block cipher Кузнечик (Kuznechik) (RFC 7801) +* GOST R 34.12-2015 64-bit block cipher Магма (Magma) * GOST R 34.13-2015 padding methods Known problems: diff --git a/src/cypherpunks.ru/gogost/gost3412/cipher.go b/src/cypherpunks.ru/gogost/gost3412128/cipher.go similarity index 99% rename from src/cypherpunks.ru/gogost/gost3412/cipher.go rename to src/cypherpunks.ru/gogost/gost3412128/cipher.go index 0a3b55f..9281892 100644 --- a/src/cypherpunks.ru/gogost/gost3412/cipher.go +++ b/src/cypherpunks.ru/gogost/gost3412128/cipher.go @@ -15,7 +15,7 @@ // along with this program. If not, see . // GOST 34.12-2015 128-bit (Кузнечик (Kuznechik)) block cipher. -package gost3412 +package gost3412128 const ( BlockSize = 16 diff --git a/src/cypherpunks.ru/gogost/gost3412/cipher_test.go b/src/cypherpunks.ru/gogost/gost3412128/cipher_test.go similarity index 99% rename from src/cypherpunks.ru/gogost/gost3412/cipher_test.go rename to src/cypherpunks.ru/gogost/gost3412128/cipher_test.go index c65a4b4..afccfcb 100644 --- a/src/cypherpunks.ru/gogost/gost3412/cipher_test.go +++ b/src/cypherpunks.ru/gogost/gost3412128/cipher_test.go @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -package gost3412 +package gost3412128 import ( "bytes" diff --git a/src/cypherpunks.ru/gogost/gost341264/cipher.go b/src/cypherpunks.ru/gogost/gost341264/cipher.go new file mode 100644 index 0000000..b8c4dbd --- /dev/null +++ b/src/cypherpunks.ru/gogost/gost341264/cipher.go @@ -0,0 +1,90 @@ +// GoGOST -- Pure Go GOST cryptographic functions library +// Copyright (C) 2015-2019 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, either version 3 of the License, or +// (at your option) any later version. +// +// 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 . + +// GOST 34.12-2015 64-bit (Магма (Magma)) block cipher. +package gost341264 + +import ( + "cypherpunks.ru/gogost/gost28147" +) + +const ( + BlockSize = 8 + KeySize = 32 +) + +type Cipher struct { + c *gost28147.Cipher + blk *[BlockSize]byte +} + +func NewCipher(key [KeySize]byte) *Cipher { + keyCompatible := new([KeySize]byte) + for i := 0; i < KeySize/4; i++ { + keyCompatible[i*4+0] = key[i*4+3] + keyCompatible[i*4+1] = key[i*4+2] + keyCompatible[i*4+2] = key[i*4+1] + keyCompatible[i*4+3] = key[i*4+0] + } + return &Cipher{ + c: gost28147.NewCipher(*keyCompatible, &gost28147.Gost28147_tc26_ParamZ), + blk: new([BlockSize]byte), + } +} + +func (c *Cipher) BlockSize() int { + return BlockSize +} + +func (c *Cipher) Encrypt(dst, src []byte) { + c.blk[0] = src[7] + c.blk[1] = src[6] + c.blk[2] = src[5] + c.blk[3] = src[4] + c.blk[4] = src[3] + c.blk[5] = src[2] + c.blk[6] = src[1] + c.blk[7] = src[0] + c.c.Encrypt(c.blk[:], c.blk[:]) + dst[0] = c.blk[7] + dst[1] = c.blk[6] + dst[2] = c.blk[5] + dst[3] = c.blk[4] + dst[4] = c.blk[3] + dst[5] = c.blk[2] + dst[6] = c.blk[1] + dst[7] = c.blk[0] +} + +func (c *Cipher) Decrypt(dst, src []byte) { + c.blk[0] = src[7] + c.blk[1] = src[6] + c.blk[2] = src[5] + c.blk[3] = src[4] + c.blk[4] = src[3] + c.blk[5] = src[2] + c.blk[6] = src[1] + c.blk[7] = src[0] + c.c.Decrypt(c.blk[:], c.blk[:]) + dst[0] = c.blk[7] + dst[1] = c.blk[6] + dst[2] = c.blk[5] + dst[3] = c.blk[4] + dst[4] = c.blk[3] + dst[5] = c.blk[2] + dst[6] = c.blk[1] + dst[7] = c.blk[0] +} diff --git a/src/cypherpunks.ru/gogost/gost341264/cipher_test.go b/src/cypherpunks.ru/gogost/gost341264/cipher_test.go new file mode 100644 index 0000000..592c121 --- /dev/null +++ b/src/cypherpunks.ru/gogost/gost341264/cipher_test.go @@ -0,0 +1,49 @@ +// GoGOST -- Pure Go GOST cryptographic functions library +// Copyright (C) 2015-2019 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, either version 3 of the License, or +// (at your option) any later version. +// +// 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 gost341264 + +import ( + "bytes" + "crypto/cipher" + "testing" +) + +func TestCipherInterface(t *testing.T) { + var key [32]byte + var _ cipher.Block = NewCipher(key) +} + +func TestVector(t *testing.T) { + key := [KeySize]byte{ + 0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88, + 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, 0x00, + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, + } + pt := [BlockSize]byte{0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10} + ct := [BlockSize]byte{0x4e, 0xe9, 0x01, 0xe5, 0xc2, 0xd8, 0xca, 0x3d} + c := NewCipher(key) + dst := make([]byte, BlockSize) + c.Encrypt(dst, pt[:]) + if bytes.Compare(dst, ct[:]) != 0 { + t.FailNow() + } + c.Decrypt(dst, dst) + if bytes.Compare(dst, pt[:]) != 0 { + t.FailNow() + } +}