Merge pull request #1 from kpetku/drop-libsodium-dep

remove libsodium dependency in favor of the native go/crypto ed25519 library
This commit is contained in:
idk
2021-05-07 20:07:10 -07:00
committed by GitHub
4 changed files with 59 additions and 57 deletions

View File

@ -9,7 +9,6 @@ Install required dependencies
This example assumes Ubuntu 16.04 This example assumes Ubuntu 16.04
```sh ```sh
sudo apt-get install pkg-config libsodium-dev
go get github.com/hkparker/go-i2p go get github.com/hkparker/go-i2p
go get github.com/Sirupsen/logrus go get github.com/Sirupsen/logrus
go get github.com/stretchr/testify/assert go get github.com/stretchr/testify/assert

View File

@ -1,8 +1,7 @@
FROM golang FROM golang
RUN apt-get update && \ RUN apt-get update && \
apt-get upgrade -y && \ apt-get upgrade -y
apt-get install libsodium-dev -y
RUN go get github.com/dvyukov/go-fuzz/go-fuzz RUN go get github.com/dvyukov/go-fuzz/go-fuzz
RUN go get github.com/dvyukov/go-fuzz/go-fuzz-build RUN go get github.com/dvyukov/go-fuzz/go-fuzz-build

View File

@ -1,54 +1,37 @@
package crypto package crypto
/*
#cgo pkg-config: libsodium
#include <sodium.h>
#include <stdint.h>
*/
import "C"
import ( import (
"crypto/ed25519"
"crypto/sha512" "crypto/sha512"
"errors" "errors"
"fmt"
) )
type Ed25519PublicKey [32]byte type Ed25519PublicKey []byte
type Ed25519Verifier struct { type Ed25519Verifier struct {
k [32]C.uchar k []byte
} }
func (k Ed25519PublicKey) NewVerifier() (v Verifier, err error) { func (k Ed25519PublicKey) NewVerifier() (v Verifier, err error) {
ev := new(Ed25519Verifier) temp := new(Ed25519Verifier)
for i, b := range k { temp.k = k
ev.k[i] = C.uchar(b) v = temp
} return temp, nil
v = ev
return
} }
func (v *Ed25519Verifier) VerifyHash(h, sig []byte) (err error) { func (v *Ed25519Verifier) VerifyHash(h, sig []byte) (err error) {
if len(sig) == C.crypto_sign_BYTES { if len(sig) != ed25519.SignatureSize {
// valid size of sig
// copy signature and hash
var csig, ch [32]C.uchar
for i, b := range h {
ch[i] = C.uchar(b)
}
for i, b := range sig {
csig[i] = C.uchar(b)
}
// verify
if C.crypto_sign_verify_detached(&csig[0], &ch[0], C.ulonglong(32), &v.k[0]) == 0 {
// valid signature
} else {
// bad signature
err = ErrInvalidSignature
}
} else {
// bad size of sig
err = ErrBadSignatureSize err = ErrBadSignatureSize
return
}
if len(v.k) != ed25519.PublicKeySize {
err = errors.New("failed to verify: invalid ed25519 public key size")
return
}
ok := ed25519.Verify(v.k, h, sig)
if !ok {
err = errors.New("failed to verify: invalid signature")
} }
return return
} }
@ -59,35 +42,23 @@ func (v *Ed25519Verifier) Verify(data, sig []byte) (err error) {
return return
} }
type Ed25519PrivateKey [32]byte type Ed25519PrivateKey ed25519.PrivateKey
type Ed25519Signer struct { type Ed25519Signer struct {
k [32]C.uchar k []byte
} }
func (s *Ed25519Signer) Sign(data []byte) (sig []byte, err error) { func (s *Ed25519Signer) Sign(data []byte) (sig []byte, err error) {
if len(s.k) != ed25519.PrivateKeySize {
err = errors.New("failed to sign: invalid ed25519 private key size")
return
}
h := sha512.Sum512(data) h := sha512.Sum512(data)
sig, err = s.SignHash(h[:]) sig, err = s.SignHash(h[:])
return return
} }
func (s *Ed25519Signer) SignHash(h []byte) (sig []byte, err error) { func (s *Ed25519Signer) SignHash(h []byte) (sig []byte, err error) {
var ch [32]C.uchar sig = ed25519.Sign(s.k, h)
for i, b := range h {
ch[i] = C.uchar(b)
}
var csig [32]C.uchar
var smlen_p C.ulonglong
res := C.crypto_sign_detached(&csig[0], &smlen_p, &ch[0], C.ulonglong(32), &s.k[0])
if res == 0 {
// success signing
sig = make([]byte, 32)
for i, b := range csig {
sig[i] = byte(b)
}
} else {
// failed signing
err = errors.New(fmt.Sprintf("failed to sign: crypto_sign_detached exit code %d", int(res)))
}
return return
} }

View File

@ -1,9 +1,42 @@
package crypto package crypto
import ( import (
"crypto/ed25519"
"crypto/rand"
"io"
"testing" "testing"
) )
func TestEd25519(t *testing.T) { func TestEd25519(t *testing.T) {
var pubKey Ed25519PublicKey
signer := new(Ed25519Signer)
pub, priv, err := ed25519.GenerateKey(rand.Reader)
if err != nil {
t.Log("Failed to generate ed25519 test key")
t.Fail()
}
pubKey = []byte(pub)
signer.k = []byte(priv)
message := make([]byte, 123)
io.ReadFull(rand.Reader, message)
sig, err := signer.Sign(message)
if err != nil {
t.Log("Failed to sign message")
t.Fail()
}
verifier, err := pubKey.NewVerifier()
if err != nil {
t.Logf("Error from verifier: %s", err)
t.Fail()
}
err = verifier.Verify(message, sig)
if err != nil {
t.Log("Failed to verify message")
t.Fail()
}
} }