mirror of
https://github.com/emmansun/gmsm.git
synced 2025-04-26 04:06:18 +08:00
update LengthPreservingMode interface
This commit is contained in:
parent
e5effb8bb9
commit
e8f39ed529
@ -21,7 +21,7 @@ func BenchmarkSM4HCTREncrypt1K(b *testing.B) {
|
|||||||
b.SetBytes(int64(len(buf)))
|
b.SetBytes(int64(len(buf)))
|
||||||
b.ResetTimer()
|
b.ResetTimer()
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
hctr.Encrypt(buf, buf)
|
hctr.EncryptBytes(buf, buf)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,29 +12,32 @@ import (
|
|||||||
// A LengthPreservingMode represents a block cipher running in a length preserving mode (HCTR,
|
// A LengthPreservingMode represents a block cipher running in a length preserving mode (HCTR,
|
||||||
// HCTR2 etc).
|
// HCTR2 etc).
|
||||||
type LengthPreservingMode interface {
|
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
|
// src must be NOT smaller than block size. Dst and src must overlap
|
||||||
// entirely or not at all.
|
// 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
|
// 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.
|
// 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.
|
// 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
|
// src must be NOT smaller than block size. Dst and src must overlap
|
||||||
// entirely or not at all.
|
// entirely or not at all.
|
||||||
//
|
//
|
||||||
// If len(dst) < len(src), Decrypt should panic. It is acceptable
|
// If len(dst) < len(src), DecryptBytes should panic. It is acceptable
|
||||||
// to pass a dst bigger than src, and in that case, Decrypt will
|
// 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.
|
// 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.
|
// 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
|
// hctrFieldElement represents a value in GF(2¹²⁸). In order to reflect the HCTR
|
||||||
@ -101,6 +104,10 @@ type hctr struct {
|
|||||||
productTable [16]hctrFieldElement
|
productTable [16]hctrFieldElement
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (h *hctr) BlockSize() int {
|
||||||
|
return blockSize
|
||||||
|
}
|
||||||
|
|
||||||
// NewHCTR returns a [LengthPreservingMode] which encrypts/decrypts useing the given [Block]
|
// 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.
|
// 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) {
|
func NewHCTR(cipher _cipher.Block, tweak, hkey []byte) (LengthPreservingMode, error) {
|
||||||
@ -164,7 +171,7 @@ func (h *hctr) mul(y *hctrFieldElement) {
|
|||||||
func (h *hctr) updateBlock(block []byte, y *hctrFieldElement) {
|
func (h *hctr) updateBlock(block []byte, y *hctrFieldElement) {
|
||||||
y.low ^= binary.BigEndian.Uint64(block)
|
y.low ^= binary.BigEndian.Uint64(block)
|
||||||
y.high ^= binary.BigEndian.Uint64(block[8:blockSize])
|
y.high ^= binary.BigEndian.Uint64(block[8:blockSize])
|
||||||
h.mul(y)
|
h.mul(y)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Universal Hash Function.
|
// Universal Hash Function.
|
||||||
@ -200,7 +207,7 @@ func (h *hctr) uhash(m []byte, out *[blockSize]byte) {
|
|||||||
binary.BigEndian.PutUint64(out[8:], y.high)
|
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) {
|
if len(ciphertext) < len(plaintext) {
|
||||||
panic("hctr: ciphertext is smaller than plaintext")
|
panic("hctr: ciphertext is smaller than plaintext")
|
||||||
}
|
}
|
||||||
@ -225,7 +232,7 @@ func (h *hctr) Encrypt(ciphertext, plaintext []byte) {
|
|||||||
subtle.XORBytes(ciphertext, z2[:], z1[:])
|
subtle.XORBytes(ciphertext, z2[:], z1[:])
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *hctr) Decrypt(plaintext, ciphertext []byte) {
|
func (h *hctr) DecryptBytes(plaintext, ciphertext []byte) {
|
||||||
if len(plaintext) < len(ciphertext) {
|
if len(plaintext) < len(ciphertext) {
|
||||||
panic("hctr: plaintext is smaller than cihpertext")
|
panic("hctr: plaintext is smaller than cihpertext")
|
||||||
}
|
}
|
||||||
|
@ -62,12 +62,12 @@ func TestHCTR(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
hctr.Encrypt(got, plaintext)
|
hctr.EncryptBytes(got, plaintext)
|
||||||
if !bytes.Equal(got, ciphertext) {
|
if !bytes.Equal(got, ciphertext) {
|
||||||
t.Fatalf("%v case encrypt failed, got %x\n", i+1, got)
|
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) {
|
if !bytes.Equal(got, plaintext) {
|
||||||
t.Fatalf("%v case decrypt failed, got %x\n", i+1, got)
|
t.Fatalf("%v case decrypt failed, got %x\n", i+1, got)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user