X-Git-Url: http://www.git.cypherpunks.ru/?a=blobdiff_plain;f=mgm%2Fmul128.go;fp=mgm%2Fmul128.go;h=07f105b8b4e6e8855bb9eb47a3b9807e95907145;hb=7e8907d3f9c6eeec0a49e563923cb0aab0e9aeac;hp=0000000000000000000000000000000000000000;hpb=d023c8db1c87409d20fbfe4f2f3237922f009fe5;p=gogost.git diff --git a/mgm/mul128.go b/mgm/mul128.go new file mode 100644 index 0000000..07f105b --- /dev/null +++ b/mgm/mul128.go @@ -0,0 +1,68 @@ +// GoGOST -- Pure Go GOST cryptographic functions library +// Copyright (C) 2015-2021 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 mgm + +import ( + "math/big" +) + +const Mul128MaxBit = 128 - 1 + +var R128 = big.NewInt(0).SetBytes([]byte{ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87, +}) + +type mul128 struct { + x *big.Int + y *big.Int + z *big.Int + buf [16]byte +} + +func newMul128() *mul128 { + return &mul128{ + x: big.NewInt(0), + y: big.NewInt(0), + z: big.NewInt(0), + } +} + +func (mul *mul128) Mul(x, y []byte) []byte { + mul.x.SetBytes(x) + mul.y.SetBytes(y) + mul.z.SetInt64(0) + for mul.y.BitLen() != 0 { + if mul.y.Bit(0) == 1 { + mul.z.Xor(mul.z, mul.x) + } + if mul.x.Bit(Mul128MaxBit) == 1 { + mul.x.SetBit(mul.x, Mul128MaxBit, 0) + mul.x.Lsh(mul.x, 1) + mul.x.Xor(mul.x, R128) + } else { + mul.x.Lsh(mul.x, 1) + } + mul.y.Rsh(mul.y, 1) + } + zBytes := mul.z.Bytes() + rem := len(x) - len(zBytes) + for i := 0; i < rem; i++ { + mul.buf[i] = 0 + } + copy(mul.buf[rem:], zBytes) + return mul.buf[:] +}