Files
2026-05-27 23:03:00 +08:00

105 lines
2.5 KiB
Go

package blockmode_test
import (
"bytes"
"encoding/hex"
"fmt"
"xdx.jelly/xgcl/sm/sm4"
"xdx.jelly/xgcl/utils/blockmode"
)
func ExampleWrap() {
// 将一个cipher.Block接口包装为EcbCbcEncBlockMode。适用于软实现的cipher.Block。
// 如果是密码机,则应该实现自己的EcbCbcEncBlockMode。因为cipher.Block只是对一个分
// 组进行计算,多个分组会反复调用密码机。
key, _ := hex.DecodeString("2d3edc27837fac8325261729fb875a09")
block, _ := sm4.NewCipher(key)
blockMode := blockmode.Wrap(block)
fmt.Println(blockMode.BlockSize())
// Output: 16
}
func ExampleNewGCM() {
// ECBBlockMode 可以调用密码机实现.
key, _ := hex.DecodeString("2d3edc27837fac8325261729fb875a09")
block, _ := sm4.NewCipher(key)
ecbBlockMode := blockmode.Wrap(block)
nonce, _ := hex.DecodeString("5b5e2f4b0e204cc7d2db5170")
// plaintext也可以为空,则为对additional data做mac
plaintext, _ := hex.DecodeString("010203040506070809")
// ad也可以为空
ad, _ := hex.DecodeString("0a0b0c0d0e0f")
gcm, err := blockmode.NewGCM(ecbBlockMode)
if err != nil {
panic(err)
}
// 用cipher.AEAD.Seal一次性完成加密计算. ct可以预先分配好,也可以传nil。
// ct1 = ciphertext || tag
ct1 := make([]byte, len(plaintext)+gcm.Overhead())
ct1 = gcm.Seal(ct1[:0], nonce, plaintext, ad) // 密文会append在dst后
// ct1 := gcm.Seal(nil, nonce, plaintext, ad) // 由Seal分配内存
pt1, err := gcm.Open(nil, nonce, ct1, ad)
if err != nil {
panic(err)
}
fmt.Println(bytes.Compare(pt1, plaintext) == 0)
// 也可以用Init-(SpecifyADD)-Update-Final三步完成
if err := gcm.EncryptInit(nonce); err != nil {
panic(err)
}
// 如果有additional data,必须在Init后,Update前调用SpecifyADD传入additional data.
// 不调用则表示additional data为空
gcm.SpecifyADD(ad)
var ct2 []byte
// Update明文
for i := 0; i < len(plaintext); i++ {
ct, err := gcm.EncryptUpdate(nil, []byte{plaintext[i]})
if err != nil {
panic(err)
}
// 处理本次Update得到的密文
ct2 = append(ct2, ct...)
}
ct, err := gcm.EncryptFinal(nil)
if err != nil {
panic(err)
}
ct2 = append(ct2, ct...)
if err := gcm.DecryptInit(nonce); err != nil {
panic(err)
}
gcm.SpecifyADD(ad)
pt2, err := gcm.DecryptUpdate(nil, ct2)
if err != nil {
panic(err)
}
pt2, err = gcm.DecryptFinal(pt2)
fmt.Println(bytes.Compare(pt2, plaintext) == 0)
// Output: true
// true
}
func ExampleNewCCM() {
// Output:
}
func ExampleNewCTR() {
// Output:
}
func ExampleNewXTS() {
// Output:
}