update LengthPreservingMode interface

This commit is contained in:
emmansun 2023-12-04 10:27:26 +08:00
parent e5effb8bb9
commit e8f39ed529
3 changed files with 22 additions and 15 deletions

View File

@ -21,7 +21,7 @@ func BenchmarkSM4HCTREncrypt1K(b *testing.B) {
b.SetBytes(int64(len(buf)))
b.ResetTimer()
for i := 0; i < b.N; i++ {
hctr.Encrypt(buf, buf)
hctr.EncryptBytes(buf, buf)
}
}

View File

@ -12,29 +12,32 @@ import (
// A LengthPreservingMode represents a block cipher running in a length preserving mode (HCTR,
// HCTR2 etc).
type LengthPreservingMode interface {
// Encrypt encrypts a number of plaintext bytes. The length of
// EncryptBytes encrypts a number of plaintext bytes. The length of
// src must be NOT smaller than block size. Dst and src must overlap
// entirely or not at all.
//
// If len(dst) < len(src), Encrypt should panic. It is acceptable
// If len(dst) < len(src), EncryptBytes should panic. It is acceptable
// to pass a dst bigger than src, and in that case, Encrypt will
// only update dst[:len(src)] and will not touch the rest of dst.
//
// Multiple calls to Encrypt behave NOT same as if the concatenation of
// Multiple calls to EncryptBytes behave NOT same as if the concatenation of
// the src buffers was passed in a single run.
Encrypt(dst, src []byte)
EncryptBytes(dst, src []byte)
// Decrypt decrypts a number of ciphertext bytes. The length of
// DecryptBytes decrypts a number of ciphertext bytes. The length of
// src must be NOT smaller than block size. Dst and src must overlap
// entirely or not at all.
//
// If len(dst) < len(src), Decrypt should panic. It is acceptable
// to pass a dst bigger than src, and in that case, Decrypt will
// If len(dst) < len(src), DecryptBytes should panic. It is acceptable
// to pass a dst bigger than src, and in that case, DecryptBytes will
// only update dst[:len(src)] and will not touch the rest of dst.
//
// Multiple calls to Decrypt behave NOT same as if the concatenation of
// Multiple calls to DecryptBytes behave NOT same as if the concatenation of
// the src buffers was passed in a single run.
Decrypt(dst, src []byte)
DecryptBytes(dst, src []byte)
// BlockSize returns the mode's block size.
BlockSize() int
}
// hctrFieldElement represents a value in GF(2¹²⁸). In order to reflect the HCTR
@ -101,6 +104,10 @@ type hctr struct {
productTable [16]hctrFieldElement
}
func (h *hctr) BlockSize() int {
return blockSize
}
// NewHCTR returns a [LengthPreservingMode] which encrypts/decrypts useing the given [Block]
// in HCTR mode. The lenght of tweak and hash key must be the same as the [Block]'s block size.
func NewHCTR(cipher _cipher.Block, tweak, hkey []byte) (LengthPreservingMode, error) {
@ -200,7 +207,7 @@ func (h *hctr) uhash(m []byte, out *[blockSize]byte) {
binary.BigEndian.PutUint64(out[8:], y.high)
}
func (h *hctr) Encrypt(ciphertext, plaintext []byte) {
func (h *hctr) EncryptBytes(ciphertext, plaintext []byte) {
if len(ciphertext) < len(plaintext) {
panic("hctr: ciphertext is smaller than plaintext")
}
@ -225,7 +232,7 @@ func (h *hctr) Encrypt(ciphertext, plaintext []byte) {
subtle.XORBytes(ciphertext, z2[:], z1[:])
}
func (h *hctr) Decrypt(plaintext, ciphertext []byte) {
func (h *hctr) DecryptBytes(plaintext, ciphertext []byte) {
if len(plaintext) < len(ciphertext) {
panic("hctr: plaintext is smaller than cihpertext")
}

View File

@ -62,12 +62,12 @@ func TestHCTR(t *testing.T) {
if err != nil {
t.Fatal(err)
}
hctr.Encrypt(got, plaintext)
hctr.EncryptBytes(got, plaintext)
if !bytes.Equal(got, ciphertext) {
t.Fatalf("%v case encrypt failed, got %x\n", i+1, got)
}
hctr.Decrypt(got, ciphertext)
hctr.DecryptBytes(got, ciphertext)
if !bytes.Equal(got, plaintext) {
t.Fatalf("%v case decrypt failed, got %x\n", i+1, got)
}