"crypto/hmac"
"encoding/binary"
"errors"
- "math/big"
)
-var (
- R64 *big.Int = big.NewInt(0)
- R128 *big.Int = big.NewInt(0)
-)
-
-func init() {
- R64.SetBytes([]byte{
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b,
- })
- R128.SetBytes([]byte{
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87,
- })
+type Mul interface {
+ Mul(x, y []byte) []byte
}
type MGM struct {
bufC []byte
padded []byte
sum []byte
-
- x *big.Int
- y *big.Int
- z *big.Int
- maxBit int
- r *big.Int
- mulBuf []byte
+ mul Mul
}
func NewMGM(cipher cipher.Block, tagSize int) (cipher.AEAD, error) {
bufC: make([]byte, blockSize),
padded: make([]byte, blockSize),
sum: make([]byte, blockSize),
- x: big.NewInt(0),
- y: big.NewInt(0),
- z: big.NewInt(0),
- mulBuf: make([]byte, blockSize),
}
if blockSize == 8 {
- mgm.maxBit = 64 - 1
- mgm.r = R64
+ mgm.mul = newMul64()
} else {
- mgm.maxBit = 128 - 1
- mgm.r = R128
+ mgm.mul = newMul128()
}
return &mgm, nil
}
xor( // sum (xor)= H_i (x) A_i
mgm.sum,
mgm.sum,
- mgm.mul(mgm.bufC, ad[:mgm.BlockSize]),
+ mgm.mul.Mul(mgm.bufC, ad[:mgm.BlockSize]),
)
incr(mgm.bufP[:mgm.BlockSize/2]) // Z_{i+1} = incr_l(Z_i)
ad = ad[mgm.BlockSize:]
mgm.padded[i] = 0
}
mgm.cipher.Encrypt(mgm.bufC, mgm.bufP)
- xor(mgm.sum, mgm.sum, mgm.mul(mgm.bufC, mgm.padded))
+ xor(mgm.sum, mgm.sum, mgm.mul.Mul(mgm.bufC, mgm.padded))
incr(mgm.bufP[:mgm.BlockSize/2])
}
xor( // sum (xor)= H_{h+j} (x) C_j
mgm.sum,
mgm.sum,
- mgm.mul(mgm.bufC, text[:mgm.BlockSize]),
+ mgm.mul.Mul(mgm.bufC, text[:mgm.BlockSize]),
)
incr(mgm.bufP[:mgm.BlockSize/2]) // Z_{h+j+1} = incr_l(Z_{h+j})
text = text[mgm.BlockSize:]
mgm.padded[i] = 0
}
mgm.cipher.Encrypt(mgm.bufC, mgm.bufP)
- xor(mgm.sum, mgm.sum, mgm.mul(mgm.bufC, mgm.padded))
+ xor(mgm.sum, mgm.sum, mgm.mul.Mul(mgm.bufC, mgm.padded))
incr(mgm.bufP[:mgm.BlockSize/2])
}
binary.BigEndian.PutUint64(mgm.bufC[mgm.BlockSize/2:], uint64(textLen))
}
// sum (xor)= H_{h+q+1} (x) (len(A) || len(C))
- xor(mgm.sum, mgm.sum, mgm.mul(mgm.bufP, mgm.bufC))
+ xor(mgm.sum, mgm.sum, mgm.mul.Mul(mgm.bufC, mgm.bufP))
mgm.cipher.Encrypt(mgm.bufP, mgm.sum) // E_K(sum)
copy(out, mgm.bufP[:mgm.TagSize]) // MSB_S(E_K(sum))
}