Skip to content

Commit

Permalink
更新
Browse files Browse the repository at this point in the history
  • Loading branch information
deatil committed Apr 12, 2024
1 parent 533213c commit 5211226
Show file tree
Hide file tree
Showing 26 changed files with 745 additions and 505 deletions.
9 changes: 4 additions & 5 deletions pkg/lakego-pkg/go-cryptobin/cipher/anubis/anubis.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ func (this *anubisCipher) crypt(out []byte, in []byte, W [][4]uint32) {
}

for r = 1; r < R; r++ {
ss = uint32sToSlice(state[:])
ss = uint32sToByteArray(state[:])

for j = 0; j < 4; j++ {
inter[j] = T[0][ss[0][j]] ^
Expand All @@ -100,9 +100,8 @@ func (this *anubisCipher) crypt(out []byte, in []byte, W [][4]uint32) {
}

// could also use U[0] here instead of T[n]
ss = uint32sToByteArray(state[:])
for j = 0; j < 4; j++ {
ss = uint32sToSlice(state[:])

inter[j] =
(T[0][ss[0][j]] & states[0]) ^
(T[1][ss[1][j]] & states[1]) ^
Expand Down Expand Up @@ -140,7 +139,7 @@ func (this *anubisCipher) expandKey(key []byte) {

// encrypt key
for r = 0; r <= R; r++ {
kk = uint32sToSlice(k)
kk = uint32sToByteArray(k)

W[r] = [4]uint32{}
for i = 0; i < N; i++ {
Expand Down Expand Up @@ -175,7 +174,7 @@ func (this *anubisCipher) expandKey(key []byte) {
}

for r = 1; r < R; r++ {
ww = uint32sToSlice(W[r][:])
ww = uint32sToByteArray(W[r][:])

for i = 0; i < 4; i++ {
W[r][i] = T[0][byte(U[0][ww[i][0]])] ^
Expand Down
2 changes: 1 addition & 1 deletion pkg/lakego-pkg/go-cryptobin/cipher/anubis/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ func uint32sToBytes(w []uint32) []byte {
return dst
}

func uint32sToSlice(w []uint32) (out [][]byte) {
func uint32sToByteArray(w []uint32) (out [][]byte) {
for _, v := range w {
out = append(out, getu32Bytes(v))
}
Expand Down
7 changes: 3 additions & 4 deletions pkg/lakego-pkg/go-cryptobin/cipher/anubis2/anubis.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ func (this *anubisCipher) crypt(ciphertext []byte, plaintext []byte, roundKey [1
*/
for r = 1; r < R; r++ {
for j = 0; j < 4; j++ {
ss = uint32sToSlice(state[:])
ss = uint32sToByteArray(state[:])

inter[j] =
T0[ss[0][j]] ^
Expand All @@ -110,9 +110,8 @@ func (this *anubisCipher) crypt(ciphertext []byte, plaintext []byte, roundKey [1
/*
* last round:
*/
ss = uint32sToByteArray(state[:])
for j = 0; j < 4; j++ {
ss = uint32sToSlice(state[:])

inter[j] =
(T0[ss[0][j]] & states[0]) ^
(T1[ss[1][j]] & states[1]) ^
Expand Down Expand Up @@ -161,7 +160,7 @@ func (this *anubisCipher) expandKey(key []byte) {
* generate R + 1 round keys:
*/
for r = 0; r <= R; r++ {
kappas = uint32sToSlice(kappa[:])
kappas = uint32sToByteArray(kappa[:])

/*
* generate r-th round key K^r:
Expand Down
2 changes: 1 addition & 1 deletion pkg/lakego-pkg/go-cryptobin/cipher/anubis2/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ func uint32sToBytes(w []uint32) []byte {
return dst
}

func uint32sToSlice(w []uint32) (out [][]byte) {
func uint32sToByteArray(w []uint32) (out [][]byte) {
for _, v := range w {
out = append(out, getu32Bytes(v))
}
Expand Down
58 changes: 58 additions & 0 deletions pkg/lakego-pkg/go-cryptobin/ecdh/ecdh.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,13 @@ package ecdh
import (
"io"
"sync"
"hash"
"errors"
"crypto"
"crypto/subtle"

"github.com/deatil/go-cryptobin/hash/sm3"
"github.com/deatil/go-cryptobin/kdf/smkdf"
)

type Curve interface {
Expand Down Expand Up @@ -53,6 +57,16 @@ type Curve interface {
PrivateKeyToPublicKey(*PrivateKey) *PublicKey
}

// ECMQVCurve
type ECMQVCurve interface {
ECMQV(sLocal, eLocal *PrivateKey, sRemote, eRemote *PublicKey) (*PublicKey, error)
}

// SM2ZACurve
type SM2ZACurve interface {
SM2ZA(h func() hash.Hash, pub *PublicKey, uid []byte) ([]byte, error)
}

// PublicKey is an ECDH public key, usually a peer's ECDH share sent over the wire.
//
// These keys can be parsed with [crypto/x509.ParsePKIXPublicKey] and encoded
Expand Down Expand Up @@ -92,6 +106,41 @@ func (k *PublicKey) Curve() Curve {
return k.NamedCurve
}

// SM2ZA ZA = H256(ENTLA || IDA || a || b || xG || yG || xA || yA).
// Compliance with GB/T 32918.2-2016 5.5
func (k *PublicKey) SM2ZA(h func() hash.Hash, uid []byte) ([]byte, error) {
if c, ok := k.NamedCurve.(SM2ZACurve); ok {
return c.SM2ZA(h, k, uid)
}

return nil, errors.New("crypto/ecdh: public key do not support SM2ZA")
}

// SM2SharedKey performs SM2 key derivation to generate shared keying data, the k was generated by SM2MQV.
func (k *PublicKey) SM2SharedKey(sPub, sRemote *PublicKey, uid, remoteUID []byte, kenLen int) ([]byte, error) {
if _, ok := k.NamedCurve.(SM2ZACurve); !ok {
return nil, errors.New("crypto/ecdh: public key do not support SM2ZA")
}

var buffer [128]byte
copy(buffer[:], k.KeyBytes[1:])

z, err := sPub.SM2ZA(sm3.New, uid)
if err != nil {
return nil, err
}

peerZ, err := sRemote.SM2ZA(sm3.New, remoteUID)
if err != nil {
return nil, err
}

copy(buffer[64:], z)
copy(buffer[96:], peerZ)

return smkdf.Key(sm3.New, buffer[:], kenLen), nil
}

// PrivateKey is an ECDH private key, usually kept secret.
//
// These keys can be parsed with [crypto/x509.ParsePKCS8PrivateKey] and encoded
Expand Down Expand Up @@ -123,6 +172,15 @@ func (k *PrivateKey) ECDH(remote *PublicKey) ([]byte, error) {
return k.NamedCurve.ECDH(k, remote)
}

// ECMQV performs a ECMQV exchange and return the shared secret.
func (k *PrivateKey) ECMQV(eLocal *PrivateKey, sRemote, eRemote *PublicKey) (*PublicKey, error) {
if c, ok := k.NamedCurve.(ECMQVCurve); ok {
return c.ECMQV(k, eLocal, sRemote, eRemote)
}

return nil, errors.New("crypto/ecdh: private key do not support ECMQV")
}

// Bytes returns a copy of the encoding of the private key.
func (k *PrivateKey) Bytes() []byte {
// Copy the private key to a fixed size buffer that can get allocated on the
Expand Down
84 changes: 83 additions & 1 deletion pkg/lakego-pkg/go-cryptobin/ecdh/ecdh_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ func Test_NistStringEqual(t *testing.T) {
assertEqual(fmt.Sprintf("%s", ecdh.GmSM2()), "GmSM2", "NistEqual")
}

func TestAllKeyBytes(t *testing.T) {
func Test_AllKeyBytes(t *testing.T) {
testKeyBytes(t, ecdh.P256())
testKeyBytes(t, ecdh.P384())
testKeyBytes(t, ecdh.P521())
Expand Down Expand Up @@ -171,3 +171,85 @@ func testKeyBytes(t *testing.T, curue ecdh.Curve) {

})
}

func Test_ECMQV(t *testing.T) {
aliceSKey, err := ecdh.GmSM2().GenerateKey(rand.Reader)
if err != nil {
t.Fatal(err)
}
aliceEKey, err := ecdh.GmSM2().GenerateKey(rand.Reader)
if err != nil {
t.Fatal(err)
}

bobSKey, err := ecdh.GmSM2().GenerateKey(rand.Reader)
if err != nil {
t.Fatal(err)
}
bobEKey, err := ecdh.GmSM2().GenerateKey(rand.Reader)
if err != nil {
t.Fatal(err)
}

bobSecret, err := bobSKey.ECMQV(bobEKey, aliceSKey.PublicKey(), aliceEKey.PublicKey())
if err != nil {
t.Fatal(err)
}

aliceSecret, err := aliceSKey.ECMQV(aliceEKey, bobSKey.PublicKey(), bobEKey.PublicKey())
if err != nil {
t.Fatal(err)
}

if !aliceSecret.Equal(bobSecret) {
t.Error("two ECMQV computations came out different")
}
}

func Test_SM2SharedKey(t *testing.T) {
aliceSKey, err := ecdh.GmSM2().GenerateKey(rand.Reader)
if err != nil {
t.Fatal(err)
}
aliceEKey, err := ecdh.GmSM2().GenerateKey(rand.Reader)
if err != nil {
t.Fatal(err)
}

bobSKey, err := ecdh.GmSM2().GenerateKey(rand.Reader)
if err != nil {
t.Fatal(err)
}
bobEKey, err := ecdh.GmSM2().GenerateKey(rand.Reader)
if err != nil {
t.Fatal(err)
}

bobSecret, err := bobSKey.ECMQV(bobEKey, aliceSKey.PublicKey(), aliceEKey.PublicKey())
if err != nil {
t.Fatal(err)
}

aliceSecret, err := aliceSKey.ECMQV(aliceEKey, bobSKey.PublicKey(), bobEKey.PublicKey())
if err != nil {
t.Fatal(err)
}

if !aliceSecret.Equal(bobSecret) {
t.Error("two ECMQV computations came out different")
}

bobKey, err := bobSecret.SM2SharedKey(aliceSKey.PublicKey(), bobSKey.PublicKey(), []byte("Alice"), []byte("Bob"), 48)
if err != nil {
t.Fatal(err)
}

aliceKey, err := aliceSecret.SM2SharedKey(aliceSKey.PublicKey(), bobSKey.PublicKey(), []byte("Alice"), []byte("Bob"), 48)
if err != nil {
t.Fatal(err)
}

if !bytes.Equal(bobKey, aliceKey) {
t.Error("two SM2SharedKey computations came out different")
}
}
56 changes: 56 additions & 0 deletions pkg/lakego-pkg/go-cryptobin/ecdh/gmsm2.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ package ecdh

import (
"io"
"hash"
"errors"
"crypto/elliptic"

"github.com/deatil/go-cryptobin/gm/sm2"
"github.com/deatil/go-cryptobin/gm/sm2/sm2curve"
)

// Multiple invocations of this function will return the same value, so it can
Expand Down Expand Up @@ -101,6 +103,60 @@ func (c *gmsm2Curve) ECDH(local *PrivateKey, remote *PublicKey) ([]byte, error)
return preMasterSecret, nil
}

func (c *gmsm2Curve) avf(secret *PublicKey) []byte {
bytes := secret.KeyBytes[1:33]

var result [32]byte
copy(result[16:], bytes[16:])

result[16] = (result[16] & 0x7f) | 0x80
return result[:]
}

func (c *gmsm2Curve) ECMQV(sLocal, eLocal *PrivateKey, sRemote, eRemote *PublicKey) (*PublicKey, error) {
// implicitSig: (sLocal + avf(eLocal.Pub) * ePriv) mod N
x2 := c.avf(eLocal.PublicKey())
t, err := sm2curve.ImplicitSig(sLocal.KeyBytes, eLocal.KeyBytes, x2)
if err != nil {
return nil, err
}

// new base point: peerPub + [x1](peerSecret)
x1 := c.avf(eRemote)
p2, err := sm2curve.NewPoint().SetBytes(eRemote.KeyBytes)
if err != nil {
return nil, err
}

if _, err := p2.ScalarMult(p2, x1); err != nil {
return nil, err
}

p1, err := sm2curve.NewPoint().SetBytes(sRemote.KeyBytes)
if err != nil {
return nil, err
}

p2.Add(p1, p2)

if _, err := p2.ScalarMult(p2, t); err != nil {
return nil, err
}

return c.NewPublicKey(p2.Bytes())
}

// CalculateZA ZA = H256(ENTLA || IDA || a || b || xG || yG || xA || yA).
// Compliance with GB/T 32918.2-2016 5.5
func (c *gmsm2Curve) SM2ZA(h func() hash.Hash, pub *PublicKey, uid []byte) ([]byte, error) {
pubkey, err := sm2.NewPublicKey(pub.Bytes())
if err != nil {
return nil, err
}

return sm2.CalculateZALegacy(pubkey, h, uid)
}

func isZero(a []byte) bool {
var acc byte
for _, b := range a {
Expand Down
15 changes: 15 additions & 0 deletions pkg/lakego-pkg/go-cryptobin/gm/sm2/sm2.go
Original file line number Diff line number Diff line change
Expand Up @@ -572,6 +572,16 @@ func VerifyWithRS(pub *PublicKey, msg []byte, r, s *big.Int, opts crypto.SignerO
return verify(pub, hashed, r, s)
}

// sm2 sign legacy
func SignLegacy(random io.Reader, priv *PrivateKey, hash []byte) (r, s *big.Int, err error) {
return sign(random, priv, hash)
}

// sm2 verify legacy
func VerifyLegacy(pub *PublicKey, hash []byte, r, s *big.Int) error {
return verify(pub, hash, r, s)
}

// sm2 sign
func sign(random io.Reader, priv *PrivateKey, hash []byte) (r, s *big.Int, err error) {
e := new(big.Int).SetBytes(hash)
Expand Down Expand Up @@ -677,6 +687,11 @@ func CalculateZA(pub *PublicKey, uid []byte) ([]byte, error) {
return calculateZA(pub, sm3.New, uid)
}

// CalculateZALegacy ZA = H256(ENTLA || IDA || a || b || xG || yG || xA || yA)
func CalculateZALegacy(pub *PublicKey, h hashFunc, uid []byte) ([]byte, error) {
return calculateZA(pub, h, uid)
}

// calculateZA ZA = H256(ENTLA || IDA || a || b || xG || yG || xA || yA)
func calculateZA(pub *PublicKey, h hashFunc, uid []byte) ([]byte, error) {
uidLen := len(uid)
Expand Down
21 changes: 21 additions & 0 deletions pkg/lakego-pkg/go-cryptobin/gm/sm2/sm2_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -615,3 +615,24 @@ func Test_SignFunc(t *testing.T) {
}
})
}

func Test_SignLegacy(t *testing.T) {
priv, err := sm2.GenerateKey(rand.Reader)
if err != nil {
t.Fatal(err)
}

pub := &priv.PublicKey

msg := []byte("test-passstest-passstest-passstest-passstest-passstest-passstest-passstest-passs")
hash := sha1.Sum(msg)

r, s, err := sm2.SignLegacy(rand.Reader, priv, hash[:])
if err != nil {
t.Error(err)
}

if sm2.VerifyLegacy(pub, hash[:], r, s) != nil {
t.Error("veri error")
}
}
Loading

0 comments on commit 5211226

Please sign in to comment.