183 lines
4.3 KiB
Go
183 lines
4.3 KiB
Go
package fpe
|
|
|
|
import (
|
|
"fmt"
|
|
"math/rand"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"xdx.jelly/xgcl/grand"
|
|
"xdx.jelly/xgcl/sm/sm4"
|
|
)
|
|
|
|
func TestNum(t *testing.T) {
|
|
N := 1000
|
|
A := make([]Numeral, N)
|
|
B := make([]Numeral, N)
|
|
|
|
for r := 2; r < 100; r++ {
|
|
radix := NewRadix(r)
|
|
for i := 1; i <= N; i++ {
|
|
for j := 0; j < i; j++ {
|
|
A[j] = Numeral(rand.Int31() % int32(r))
|
|
}
|
|
numSwitch = false
|
|
a0 := radix.Num(A[:i])
|
|
numSwitch = true
|
|
a1 := radix.Num(A[:i])
|
|
assert.Equal(t, a0.Cmp(a1), 0)
|
|
|
|
radix.Str(B[:i], a0)
|
|
assert.Equal(t, A[:i], B[:i])
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestStr(t *testing.T) {
|
|
f := Alpha
|
|
// 24948832942366750129003083595837476696096111951836798179448429117431251233398075403977925597490
|
|
A := []Numeral{
|
|
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
|
|
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
|
|
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
|
|
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
|
|
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
|
|
}
|
|
|
|
for i := 20; i <= len(A); i++ {
|
|
a := f.Num(A[:i])
|
|
B := make([]Numeral, i)
|
|
f.Str(B, a)
|
|
for j := range B {
|
|
if B[j] != A[j] {
|
|
t.Fatal()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// BenchmarkAlphabet-10 1158810 1020 ns/op 88 B/op 3 allocs/op
|
|
// BenchmarkAlphabet-10 3776529 310.4 ns/op 96 B/op 4 allocs/op
|
|
func BenchmarkNum(b *testing.B) {
|
|
f := Alpha
|
|
A := []Numeral{
|
|
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
|
|
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
|
|
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
|
|
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
|
|
}
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
f.Num(A)
|
|
}
|
|
}
|
|
|
|
// BenchmarkStr-10 556981 2130 ns/op 104 B/op 2 allocs/op
|
|
// BenchmarkStr-10 3134851 382.2 ns/op 104 B/op 2 allocs/op
|
|
func BenchmarkStr(b *testing.B) {
|
|
f := Alpha
|
|
A := []Numeral{
|
|
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
|
|
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
|
|
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
|
|
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
|
|
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
|
|
}
|
|
|
|
a := f.Num(A)
|
|
B := make([]Numeral, len(A))
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
f.Str(B, a)
|
|
}
|
|
}
|
|
|
|
func TestFF1(t *testing.T) {
|
|
// fmt.Printf("%x\n", ^uint64(15))
|
|
// 密钥
|
|
key := grand.GetRandom(16)
|
|
// 使用SM4加密算法
|
|
b, _ := sm4.NewCipher(key)
|
|
// tweak
|
|
T := grand.GetRandom(16)
|
|
|
|
// interface FPE
|
|
f := NewFF1(b, NewAlphabet("abcdefghijklmnopqrstuvwxyz "))
|
|
|
|
plainString0 := "hello world"
|
|
plain0, err := f.Encode(plainString0)
|
|
assert.Nil(t, err)
|
|
|
|
cipher, err := f.Encrypt(T, plain0)
|
|
assert.Nil(t, err)
|
|
|
|
cipherString, err := f.Decode(cipher)
|
|
assert.Nil(t, err)
|
|
|
|
fmt.Println("Cipher string:", cipherString)
|
|
plain1, err := f.Decrypt(T, cipher)
|
|
assert.Nil(t, err)
|
|
|
|
assert.Equal(t, plain0, plain1)
|
|
plainString1, err := f.Decode(plain1)
|
|
assert.Nil(t, err)
|
|
|
|
fmt.Println("Decrypt string:", plainString1)
|
|
assert.Equal(t, plainString0, plainString1)
|
|
}
|
|
|
|
// BenchmarkFF1-10 129781 8683 ns/op 4256 B/op 154 allocs/op
|
|
// BenchmarkFF1-10 325104 3694 ns/op 2808 B/op 99 allocs/op
|
|
func BenchmarkFF1(b *testing.B) {
|
|
key := grand.GetRandom(16)
|
|
block, _ := sm4.NewCipher(key)
|
|
T := grand.GetRandom(16)
|
|
f := NewFF1(block, Printable)
|
|
|
|
plainString0 := "hello world"
|
|
plain0, _ := f.Encode(plainString0)
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
_, _ = f.Encrypt(T, plain0)
|
|
}
|
|
}
|
|
|
|
// // 密文长度 加密速率(MBps)
|
|
// // 32 2.55
|
|
// // 64 3.99
|
|
// // 128 3.58
|
|
// // 256 3.82
|
|
// // 512 3.65
|
|
// // 1024 3.15
|
|
// // 2048 2.38
|
|
// // 4096 1.58
|
|
// // 8192 0.94
|
|
func TestSpeed(t *testing.T) {
|
|
key := grand.GetRandom(16)
|
|
block, _ := sm4.NewCipher(key)
|
|
T := grand.GetRandom(16)
|
|
f := NewFF1(block, Printable)
|
|
|
|
fmt.Println("密文长度 加密速率(MBps)")
|
|
for plainLen, cnt := 32, 10000; plainLen < 10000; plainLen, cnt = plainLen*2, cnt/2 {
|
|
b := make([]byte, plainLen)
|
|
for i := range b {
|
|
b[i] = byte(rand.Uint32()%26 + 'a')
|
|
}
|
|
plain := string(b)
|
|
|
|
start := time.Now()
|
|
for i := 0; i < cnt; i++ {
|
|
n, _ := f.Encode(plain)
|
|
_, _ = f.Encrypt(T, n)
|
|
|
|
}
|
|
end := time.Now()
|
|
elapsed := end.Sub(start)
|
|
fmt.Printf("%4d %.2f\n", plainLen, float64(len(plain)*cnt)/(1024*1024*elapsed.Seconds()))
|
|
}
|
|
}
|