init: v1.0.0
This commit is contained in:
@@ -0,0 +1,438 @@
|
||||
package sm2
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/elliptic"
|
||||
"crypto/rand"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"math/big"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"xdx.jelly/xgcl/grand"
|
||||
"xdx.jelly/xgcl/internal"
|
||||
)
|
||||
|
||||
func hexDecode(s string) []byte {
|
||||
b, err := hex.DecodeString(s)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
func TestAudit(t *testing.T) {
|
||||
if !(Auditor{}).Correctness() {
|
||||
t.Fatal("Correctness check failed")
|
||||
}
|
||||
}
|
||||
|
||||
// TestCurve test speed of sm2 curve on ScalarMult and ScalarBaseMult.
|
||||
// A litter slower than P256 curve.
|
||||
func TestCurve(t *testing.T) {
|
||||
gx, gy := Curve().Params().Gx, Curve().Params().Gy
|
||||
k := make([]byte, 32)
|
||||
grand.GenerateRandom(k)
|
||||
|
||||
count, duation := internal.SingleThreadTester(func() {
|
||||
sm2Curve.ScalarMult(gx, gy, k)
|
||||
})
|
||||
fmt.Printf("SM2Curve ScalarMult: %d times/Sec\n", int(internal.Rate(count, duation)))
|
||||
|
||||
count, duation = internal.SingleThreadTester(func() {
|
||||
sm2Curve.ScalarBaseMult(k)
|
||||
})
|
||||
fmt.Printf("SM2Curve ScalarBaseMult: %d times/Sec\n", int(internal.Rate(count, duation)))
|
||||
}
|
||||
|
||||
// TestP256Curve test speed of P256 curve on ScalarMult and ScalarBaseMult.
|
||||
func TestP256Curve(t *testing.T) {
|
||||
c := elliptic.P256()
|
||||
gx, gy := c.Params().Gx, c.Params().Gy
|
||||
k := make([]byte, 32)
|
||||
grand.GenerateRandom(k)
|
||||
|
||||
count, duation := internal.SingleThreadTester(func() {
|
||||
c.ScalarMult(gx, gy, k)
|
||||
})
|
||||
fmt.Printf("P256 ScalarMult: %d times/Sec\n", int(internal.Rate(count, duation)))
|
||||
|
||||
count, duation = internal.SingleThreadTester(func() {
|
||||
c.ScalarBaseMult(k)
|
||||
})
|
||||
fmt.Printf("P256 ScalarBaseMult: %d times/Sec\n", int(internal.Rate(count, duation)))
|
||||
}
|
||||
|
||||
// func TestKeyGen(t *testing.T) {
|
||||
// sk, _ := GenPrivateKey(grand.GetRandom(32))
|
||||
// pk := GenPublicKey(sk)
|
||||
|
||||
// sm4Key := make([]byte, 16)
|
||||
// buf := make([]byte, 0)
|
||||
// fp, err := os.OpenFile("/Users/fengwd/Codes/go/src/xdx.jelly/xgcl/sm/sm2/key", os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666)
|
||||
// if err != nil {
|
||||
// panic("openfile failed")
|
||||
// }
|
||||
// for i := 0; i < 1000; i++ {
|
||||
// buf = buf[:0]
|
||||
// if i%1000 == 0 {
|
||||
// fmt.Printf("%d\n", i)
|
||||
// }
|
||||
// usk, _ := GenPrivateKey(grand.GetRandom(32))
|
||||
// upk := GenPublicKey(sk)
|
||||
// grand.GenerateRandom(sm4Key)
|
||||
// tmp, _ := usk.MarshalBinary()
|
||||
// buf = append(buf, tmp...)
|
||||
// tmp, _ = upk.MarshalBinary()
|
||||
// buf = append(buf, tmp...)
|
||||
// buf = padding.P7.Pad(buf, 16)
|
||||
// buf, _ = sm4.EncryptECB(buf, sm4Key, buf)
|
||||
// cipher, _ := Encrypt(pk, sm4Key, nil)
|
||||
// tmp, _ = cipher.MarshalBinary()
|
||||
// buf = append(buf, tmp...)
|
||||
// fp.Write(buf)
|
||||
|
||||
// }
|
||||
|
||||
// fp.Close()
|
||||
// }
|
||||
|
||||
func TestKeyValid(t *testing.T) {
|
||||
{
|
||||
k, _ := hex.DecodeString("000001000000000000000000000000000000000000000000000000000000000000000000972b80815e2c29e837fd006dc05534373950b221a090ad8dbeaa6e787bbbc85b00000000000000000000000000000000000000000000000000000000000000009ec521bc8fe61d2cfbc3bb8d4748ee6eb56e33d5955dba236f21085264095fa8")
|
||||
// pk := NewPublicKey()
|
||||
pk := &PublicKey{}
|
||||
pk.UnmarshalBinary(k)
|
||||
b, _ := pk.MarshalBinary()
|
||||
assert.Equal(t, k, b)
|
||||
}
|
||||
{
|
||||
k := NewPrivateKey().Random(grand.Reader)
|
||||
pk := (&PublicKey{}).Generate(k)
|
||||
b, _ := pk.MarshalBinary()
|
||||
pk1 := &PublicKey{}
|
||||
pk1.UnmarshalBinary(b)
|
||||
assert.True(t, pk1.Equal(pk))
|
||||
assert.True(t, pk.IsValid())
|
||||
assert.True(t, pk1.IsValid())
|
||||
}
|
||||
}
|
||||
func TestPreComputeWithIdAndPubkey(t *testing.T) {
|
||||
var r [32]byte
|
||||
r[31] = 1
|
||||
sk, _ := GenPrivateKey(r[:])
|
||||
pk := GenPublicKey(sk)
|
||||
e := PreComputeWithIdAndPubkey(nil, pk)
|
||||
assert.Equal(t, e, hexDecode("5b32bfe35482899b195d72c09d33ccdb465b2ded883240ff91f120a68bc91de8"))
|
||||
}
|
||||
|
||||
func TestSignStd(t *testing.T) {
|
||||
m := []byte("message digest")
|
||||
buf, _ := hex.DecodeString("3945208F7B2144B13F36E38AC6D39F95889393692860B51A42FB81EF4DF7C5B8")
|
||||
d, _ := GenPrivateKey(buf)
|
||||
pk := GenPublicKey(d)
|
||||
e := PreComputeWithIdAndPubkeyAndMessage(nil, m, pk)
|
||||
k, err := hex.DecodeString("59276E27D506861A16680F3AD9C02DCCEF3CC1FA3CDBE4CE6D54B80DEAC1BC21")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
fmt.Printf("%x\n", e)
|
||||
fmt.Println(pk.X.Text(16))
|
||||
fmt.Println(pk.Y.Text(16))
|
||||
|
||||
sig, err := Sign(e, k, d)
|
||||
if err != nil {
|
||||
t.Log()
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
data, err := sig.MarshalBinary()
|
||||
if err != nil {
|
||||
t.Log()
|
||||
t.Fail()
|
||||
}
|
||||
if hex.EncodeToString(data) != "0000000000000000000000000000000000000000000000000000000000000000f5a03b0648d2c4630eeac513e1bb81a15944da3827d5b74143ac7eaceee720b30000000000000000000000000000000000000000000000000000000000000000b1b6aa29df212fd8763182bc0d421ca1bb9038fd1f7f42d4840b69c485bbc1aa" {
|
||||
t.Log()
|
||||
t.Fail()
|
||||
}
|
||||
assert.True(t, Verify(e, pk, sig))
|
||||
}
|
||||
|
||||
func TestSign(t *testing.T) {
|
||||
e := hexDecode("3854C463FA3F73783621B1CE4EF83F7C78048AAC79B221FCDD290866CC131174")
|
||||
k := hexDecode("F026AD9A7EB94401A800C8D8C3277E69972C7F3778ACE4D537012023EDFB69FF")
|
||||
d, err := GenPrivateKey(hexDecode("C242939DDAB6FCC07B6676C07D2DC117EC68A09142C25C008630B9756786162D"))
|
||||
assert.Nil(t, err)
|
||||
|
||||
sig, err := Sign(e, k, d)
|
||||
assert.Nil(t, err)
|
||||
|
||||
data, err := sig.MarshalBinary()
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, data, hexDecode("00000000000000000000000000000000000000000000000000000000000000006e5db49dbd0992b97040080a96003c721cdb9cf64c88d74321fc2f630adf377400000000000000000000000000000000000000000000000000000000000000002f6dff453dfc8d7a506d3f52301bee529e62fddd38948f0d5d2cbcbc55900cfa"))
|
||||
|
||||
sig1 := NewSignature()
|
||||
assert.Nil(t, sig1.UnmarshalBinary(data))
|
||||
assert.Equal(t, sig1.R.Cmp(sig.R), 0)
|
||||
assert.Equal(t, sig1.S.Cmp(sig.S), 0)
|
||||
|
||||
pk := GenPublicKey(d)
|
||||
fmt.Println(pk)
|
||||
data, err = pk.MarshalBinary()
|
||||
assert.Nil(t, err)
|
||||
|
||||
pk1 := NewPublicKey()
|
||||
assert.Nil(t, pk1.UnmarshalBinary(data))
|
||||
assert.Equal(t, fmt.Sprintf("%#v", pk), fmt.Sprintf("%#v", pk1))
|
||||
|
||||
assert.True(t, Verify(e, pk, sig))
|
||||
}
|
||||
|
||||
// (r,s)是e,pk的签名,则(r, -(s + 2rd/(1+d))也是e,pk的签名
|
||||
func TestSignDual(t *testing.T) {
|
||||
e := hexDecode("3854C463FA3F73783621B1CE4EF83F7C78048AAC79B221FCDD290866CC131174")
|
||||
k := hexDecode("F026AD9A7EB94401A800C8D8C3277E69972C7F3778ACE4D537012023EDFB69FF")
|
||||
sk, _ := GenPrivateKey(hexDecode("C242939DDAB6FCC07B6676C07D2DC117EC68A09142C25C008630B9756786162D"))
|
||||
pk := GenPublicKey(sk)
|
||||
|
||||
var sig *Signature
|
||||
sig, err := Sign(e, k, sk)
|
||||
assert.Nil(t, err)
|
||||
|
||||
assert.True(t, Verify(e, pk, sig))
|
||||
|
||||
// s' = -(s + 2rd(1+d)^-1)
|
||||
tmp := big.NewInt(1)
|
||||
tmp.Add(tmp, sk.D)
|
||||
tmp.ModInverse(tmp, OrderN())
|
||||
tmp.Mul(tmp, sk.D)
|
||||
tmp.Mul(tmp, sig.R)
|
||||
tmp.Lsh(tmp, 1)
|
||||
tmp.Add(tmp, sig.S)
|
||||
tmp.Mod(tmp, OrderN())
|
||||
tmp.Sub(OrderN(), tmp)
|
||||
sig.S.Set(tmp)
|
||||
|
||||
assert.True(t, Verify(e, pk, sig))
|
||||
}
|
||||
|
||||
// 已知公钥P, 则可任意取r,s,并构造e = r-X(sG+(r+s)P)
|
||||
// verify(r,s,P,e) = true
|
||||
func TestSignForge(t *testing.T) {
|
||||
|
||||
d, err := hex.DecodeString("C242939DDAB6FCC07B6676C07D2DC117EC68A09142C25C008630B9756786162D")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
sk, _ := GenPrivateKey(d)
|
||||
pk := GenPublicKey(sk)
|
||||
|
||||
r, _ := rand.Int(grand.Reader, OrderN())
|
||||
s, _ := rand.Int(grand.Reader, OrderN())
|
||||
|
||||
u := big.NewInt(0)
|
||||
u.Add(r, s)
|
||||
u.Mod(u, OrderN())
|
||||
x1, y1 := Curve().ScalarMult(pk.X, pk.Y, u.Bytes())
|
||||
x2, y2 := Curve().ScalarBaseMult(s.Bytes())
|
||||
x1, _ = Curve().Add(x1, y1, x2, y2)
|
||||
e := new(big.Int)
|
||||
e = e.Sub(r, x1)
|
||||
e.Mod(e, OrderN())
|
||||
|
||||
sig := new(Signature)
|
||||
sig.S = s
|
||||
sig.R = r
|
||||
|
||||
assert.True(t, Verify(e.Bytes(), pk, sig))
|
||||
|
||||
}
|
||||
|
||||
func TestEncrypt(t *testing.T) {
|
||||
sk, _ := GenPrivateKey([]byte{
|
||||
0x81, 0x98, 0x7C, 0xC9, 0x0C, 0xF5, 0x05, 0x7C,
|
||||
0x2D, 0xCA, 0xA7, 0x5D, 0x1F, 0xDD, 0xCA, 0x84,
|
||||
0xB2, 0x48, 0x62, 0xF0, 0xCA, 0xD7, 0x3C, 0x7F,
|
||||
0x67, 0x34, 0x9A, 0xE6, 0x99, 0xB9, 0x29, 0x83},
|
||||
)
|
||||
|
||||
rnd := []byte{
|
||||
0x26, 0xD6, 0x16, 0x3F, 0xA1, 0x86, 0x03, 0xEE,
|
||||
0x2F, 0x3D, 0xE8, 0x93, 0x65, 0x44, 0xD5, 0xDF,
|
||||
0x12, 0x55, 0xA2, 0xDB, 0xEB, 0xA6, 0x3A, 0xFC,
|
||||
0x0D, 0x83, 0x3E, 0xC4, 0x49, 0xD2, 0xCB, 0x45,
|
||||
}
|
||||
|
||||
msg := []byte{
|
||||
0xC3, 0x53, 0xC6, 0x8E, 0xF0, 0x5C, 0x4B, 0x34,
|
||||
0x2B, 0x37, 0x7D, 0xA0, 0x55, 0xD9, 0x09, 0xFB,
|
||||
0x1F, 0xAA, 0x42, 0x55, 0x66, 0x2F, 0x3B, 0xAB,
|
||||
0x8D, 0xDB, 0x35, 0x35, 0xE4, 0x0B, 0xC9, 0x3B,
|
||||
}
|
||||
|
||||
wantCipher := "bf6cfcb8e6295dc22777376f8385c5d6aadd5e430d11e004246d6bebf99ec5249cb9ab2f9af688c77a1bdf9f3b0816a4eab7f5da22e5dacdc1c8f6e45499874e1fc32e35744161aa0ffa6c70fc811d3b66d4cacda3c0996b54768c603c6b24e0c85cdde8ad71a258b89ddb42da900bcf4f18ab52d7841134cac581d3cf7f58f7"
|
||||
pk := GenPublicKey(sk)
|
||||
|
||||
// pk.X.Add(pk.X, gmath.BigInt1)
|
||||
// fmt.Println(hex.EncodeToString(pk.x[:]) + hex.EncodeToString(pk.y[:]))
|
||||
cipher, err := Encrypt(pk, msg, rnd)
|
||||
if err != nil {
|
||||
t.Log(err)
|
||||
t.Fail()
|
||||
return
|
||||
}
|
||||
|
||||
if hex.EncodeToString(cipher.Bytes()) != wantCipher {
|
||||
t.Log("Encrypt Failed")
|
||||
t.Log("cipher :", hex.EncodeToString(cipher.Bytes()))
|
||||
t.Log("WantCipher:", wantCipher)
|
||||
t.Fail()
|
||||
return
|
||||
}
|
||||
|
||||
// marshal test
|
||||
// t.Log(cipher)
|
||||
data, _ := cipher.MarshalBinary()
|
||||
// t.Log(hex.EncodeToString(data))
|
||||
cipher1 := NewCipher()
|
||||
if err := cipher1.UnmarshalBinary(data); err != nil {
|
||||
t.Log("unmarshal failed")
|
||||
}
|
||||
if fmt.Sprintf("%#v", cipher) != fmt.Sprintf("%#v", cipher1) {
|
||||
t.Log("Marshal Test failed")
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
//Decrypt
|
||||
decryptedMsg, err := Decrypt(sk, cipher)
|
||||
if err != nil || bytes.Compare(decryptedMsg, msg) != 0 {
|
||||
t.Log(err)
|
||||
t.Log("decryptedMsg :", hex.EncodeToString(decryptedMsg))
|
||||
t.Log("msg :", hex.EncodeToString(msg))
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// func TestErrors(t *testing.T) {
|
||||
// errors.PrintErrorInfos(os.Stdout)
|
||||
// }
|
||||
|
||||
func TestZeroHashSign(t *testing.T) {
|
||||
zeroHash := make([]byte, 32)
|
||||
|
||||
for _, curve := range []elliptic.Curve{Curve()} {
|
||||
privKey, err := GenerateKey(curve, rand.Reader)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Sign a hash consisting of all zeros.
|
||||
// r, s, err := Sign(rand.Reader, privKey, zeroHash)
|
||||
k := make([]byte, 32)
|
||||
grand.GenerateRandom(k)
|
||||
sig, err := Sign(zeroHash, k, privKey)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Confirm that it can be verified.
|
||||
if !Verify(zeroHash, privKey.Public().(*PublicKey), sig) {
|
||||
t.Errorf("zero hash signature verify failed for %T", curve)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestEncEmpty(t *testing.T) {
|
||||
sk, _ := GenPrivateKey([]byte{
|
||||
0x81, 0x98, 0x7C, 0xC9, 0x0C, 0xF5, 0x05, 0x7C,
|
||||
0x2D, 0xCA, 0xA7, 0x5D, 0x1F, 0xDD, 0xCA, 0x84,
|
||||
0xB2, 0x48, 0x62, 0xF0, 0xCA, 0xD7, 0x3C, 0x7F,
|
||||
0x67, 0x34, 0x9A, 0xE6, 0x99, 0xB9, 0x29, 0x83},
|
||||
)
|
||||
|
||||
rnd := []byte{
|
||||
0x26, 0xD6, 0x16, 0x3F, 0xA1, 0x86, 0x03, 0xEE,
|
||||
0x2F, 0x3D, 0xE8, 0x93, 0x65, 0x44, 0xD5, 0xDF,
|
||||
0x12, 0x55, 0xA2, 0xDB, 0xEB, 0xA6, 0x3A, 0xFC,
|
||||
0x0D, 0x83, 0x3E, 0xC4, 0x49, 0xD2, 0xCB, 0x45,
|
||||
}
|
||||
|
||||
msg := []byte{}
|
||||
|
||||
pk := &sk.PublicKey
|
||||
cipher, err := Encrypt(pk, msg, rnd)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
decryptedMsg, err := Decrypt(sk, cipher)
|
||||
if err != nil || bytes.Compare(decryptedMsg, msg) != 0 {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestEncLong(t *testing.T) {
|
||||
sk, err := GenerateKey(Curve(), grand.Reader)
|
||||
pk := &sk.PublicKey
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
data := make([]byte, 409600)
|
||||
if _, err := io.ReadFull(grand.Reader, data); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
cipher, err := Encrypt(pk, data, grand.GetRandom(32))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
decryptedData, err := Decrypt(sk, cipher)
|
||||
if err != nil || bytes.Compare(decryptedData, data) != 0 {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSM2Point(t *testing.T) {
|
||||
x, _ := new(big.Int).SetString("54cb2e421e7119ddbba44ff0db131e9907ed90a1b0b9a23b9d3eb890519d5cae", 16)
|
||||
y, _ := new(big.Int).SetString("389646ab568a3bd7a566e1e49b98a4d41041b2fa2cf0af74fceef65ef1e986c6", 16)
|
||||
|
||||
pk := &PublicKey{
|
||||
Curve: Curve(),
|
||||
X: x,
|
||||
Y: y,
|
||||
}
|
||||
assert.True(t, pk.IsValid())
|
||||
}
|
||||
|
||||
// func TestSM2Verify(t *testing.T) {
|
||||
// r, _ := new(big.Int).SetString("d3233fe6b680f1fc26bb4932b894af1e9e73c700554c39f407ac91c4d4d74347", 16)
|
||||
// s, _ := new(big.Int).SetString("08bc7476b0fd496287d162dfab5a68a340515b3f8647ed03f75c4d1b50aeb957", 16)
|
||||
// x, _ := new(big.Int).SetString("6a3f992330c0857eda4b914ebef614bf401266fb6168e3f90475ed1fcd3c2625", 16)
|
||||
// y, _ := new(big.Int).SetString("36341b6383d996205996aa164480bad952aa07a0db942858d103bf8f2f4b460a", 16)
|
||||
// pk := &PublicKey{
|
||||
// Curve: Curve(),
|
||||
// X: x,
|
||||
// Y: y,
|
||||
// }
|
||||
// sig := &Signature{
|
||||
// R: r,
|
||||
// S: s,
|
||||
// }
|
||||
// assert.True(t, pk.IsValid())
|
||||
// e, _ := hex.DecodeString("c3e283e5ad232e04b29d2422a88fb251cd08cad4f0e8b77cdcdd7859eb6fabd7")
|
||||
// // e = PreComputeWithIdAndPubkeyAndMessage(GetDefaultID(), e, pk)
|
||||
|
||||
// assert.True(t, Verify(e, pk, sig))
|
||||
// e, _ = hex.DecodeString("8d3eef66a23e3118a7b32a386cd1db41bc4e7a803098ee92c6b5cda43829ad96")
|
||||
// // e = PreComputeWithIdAndPubkeyAndMessage(GetDefaultID(), e, pk)
|
||||
// assert.True(t, Verify(e, pk, sig))
|
||||
// }
|
||||
Reference in New Issue
Block a user