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())) } }