Skip to content
This repository has been archived by the owner on Feb 8, 2023. It is now read-only.

Commit

Permalink
add signature.Keys and signature.KeyPairs
Browse files Browse the repository at this point in the history
  • Loading branch information
zensh committed Dec 16, 2018
1 parent d70a69b commit df01d48
Show file tree
Hide file tree
Showing 5 changed files with 157 additions and 2 deletions.
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,18 @@ func KeyPairFrom(publicKey string, privateKey ...string) (*KeyPair, error)

func (k *KeyPair) Sign(message []byte) (sig []byte)
func (k *KeyPair) Verify(message, sig []byte) bool

type Keys [][]byte
func (k Keys) Sign(message []byte) []byte
func (k Keys) Verify(message, sig []byte) bool
func (k Keys) Seal(message []byte) []byte
func (k Keys) Open(message []byte) ([]byte, bool)

type KeyPairs []*KeyPair
func (k KeyPairs) Sign(message []byte) []byte
func (k KeyPairs) Verify(message, sig []byte) bool
func (k KeyPairs) Seal(message []byte) []byte
func (k KeyPairs) Open(message []byte) ([]byte, bool)
```

password "github.com/teambition/crypto-go/password":
Expand Down
2 changes: 1 addition & 1 deletion crypto.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
)

// Version -
const Version = "3.0.1"
const Version = "3.1.0"

// Equal compares two []byte for equality without leaking timing information.
//
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/stretchr/testify v1.2.2
golang.org/x/crypto v0.0.0-20181127143415-eb0de9b17e85
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9
)

replace golang.org/x/crypto => github.com/golang/crypto v0.0.0-20181030102418-4d3f4d9ffa16
83 changes: 83 additions & 0 deletions signature/signature.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,48 @@ func VerifyPublic(publicKey, message, sig []byte) bool {
return ed25519.Verify(ed25519.PublicKey(publicKey), message, sig)
}

// Keys - struct for Sign and Verify with HmacSum & sha3.New256
type Keys [][]byte

// Sign - sign a message with HmacSum & sha3.New256
func (k Keys) Sign(message []byte) []byte {
if len(k) == 0 {
return nil
}
return crypto.HmacSum(sha3.New256, k[0], message)
}

// Verify - verify message with HmacSum & sha3.New256
func (k Keys) Verify(message, sig []byte) bool {
if len(sig) != 32 {
return false
}
for _, key := range k {
if crypto.Equal(sig, crypto.HmacSum(sha3.New256, key, message)) {
return true
}
}
return false
}

// Seal - Seal a message with HmacSum&sha3.New256
func (k Keys) Seal(message []byte) []byte {
sig := k.Sign(message)
return append(sig, message...)
}

// Open - Open a message with HmacSum&sha3.New256
func (k Keys) Open(message []byte) ([]byte, bool) {
if len(message) > 32 {
data := message[32:]
if k.Verify(data, message[:32]) {
// should return a copy data
return append(make([]byte, 0, len(data)), data...), true
}
}
return nil, false
}

// KeyPair - struct for Sign and Verify with ed25519
type KeyPair struct {
publicKey ed25519.PublicKey
Expand Down Expand Up @@ -101,3 +143,44 @@ func KeyPairFrom(publicKey string, privateKey ...string) (*KeyPair, error) {
}
return &keyPair, nil
}

// KeyPairs -
type KeyPairs []*KeyPair

// Sign - sign a message with ed25519
func (k KeyPairs) Sign(message []byte) (sig []byte) {
if len(k) == 0 {
return nil
}
return k[0].Sign(message)
}

// Verify - verify message with ed25519
func (k KeyPairs) Verify(message, sig []byte) bool {
if len(sig) != SignatureSize {
return false
}
for _, key := range k {
if key.Verify(message, sig) {
return true
}
}
return false
}

// Seal - Seal a message with ed25519
func (k KeyPairs) Seal(message []byte) []byte {
sig := k.Sign(message)
return append(sig, message...)
}

// Open - Open a message with ed25519
func (k KeyPairs) Open(message []byte) ([]byte, bool) {
if len(message) > SignatureSize {
data := message[SignatureSize:]
if k.Verify(data, message[:SignatureSize]) {
return append(make([]byte, 0, len(data)), data...), true
}
}
return nil, false
}
60 changes: 60 additions & 0 deletions signature/signature_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,33 @@ func TestCryptoSignature(t *testing.T) {
assert.False(Verify(key, []byte("test message"), sig))
})

t.Run("Keys", func(t *testing.T) {
assert := assert.New(t)
keys1 := Keys([][]byte{crypto.RandN(16)})
keys2 := Keys([][]byte{crypto.RandN(32), keys1[0]})

sig := keys1.Sign([]byte("test message"))
assert.True(keys1.Verify([]byte("test message"), sig))
assert.True(keys2.Verify([]byte("test message"), sig))
assert.False(keys1.Verify([]byte("test message1"), sig))
assert.False(keys1.Verify([]byte("test message"), sig[1:]))
assert.False(keys1.Verify([]byte("test message"), sig[:10]))

msg := []byte("你好,中国!")
data := keys2.Seal(msg)
v, ok := keys2.Open(data)
assert.True(ok)
assert.Equal(msg, v)
assert.Equal(32+len(msg), len(data))

v, ok = keys1.Open(msg)
assert.False(ok)
assert.Nil(v)
v, ok = keys2.Open(msg[:len(msg)-10])
assert.False(ok)
assert.Nil(v)
})

t.Run("SignPrivate and VerifyPublic", func(t *testing.T) {
assert := assert.New(t)
public, private, _ := ed25519.GenerateKey(nil)
Expand Down Expand Up @@ -81,4 +108,37 @@ func TestCryptoSignature(t *testing.T) {
_, err = KeyPairFrom(publicKey2, privateKey)
assert.NotNil(err)
})

t.Run("KeyPairs", func(t *testing.T) {
assert := assert.New(t)
// publicKey, privateKey := GenerateKey()
KeyPair1, err := KeyPairFrom(GenerateKey())
assert.Nil(err)
KeyPair2, err := KeyPairFrom(GenerateKey())
assert.Nil(err)

keyPairs1 := KeyPairs([]*KeyPair{KeyPair1})
keyPairs2 := KeyPairs([]*KeyPair{KeyPair2, KeyPair1})

sig := keyPairs1.Sign([]byte("test message"))
assert.True(keyPairs1.Verify([]byte("test message"), sig))
assert.True(keyPairs2.Verify([]byte("test message"), sig))
assert.False(keyPairs1.Verify([]byte("test message1"), sig))
assert.False(keyPairs1.Verify([]byte("test message"), sig[1:]))
assert.False(keyPairs1.Verify([]byte("test message"), sig[:10]))

msg := []byte("你好,中国!")
data := keyPairs2.Seal(msg)
v, ok := keyPairs2.Open(data)
assert.True(ok)
assert.Equal(msg, v)
assert.Equal(64+len(msg), len(data))

v, ok = keyPairs1.Open(msg)
assert.False(ok)
assert.Nil(v)
v, ok = keyPairs2.Open(msg[:len(msg)-10])
assert.False(ok)
assert.Nil(v)
})
}

0 comments on commit df01d48

Please sign in to comment.