105 lines
2.5 KiB
Go
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:
|
|
}
|