diff --git a/README.md b/README.md index 233324d..222f59a 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,8 @@ * [Transmitting a message](#transmitting-a-message) * [Handling errors](#handling-errors) * [Key generation](#key-generation) + * [Bindings](#bindings) + * [Android](#android) - [Contributing](#contributing) - [Security](#security) - [Support](#support) @@ -182,6 +184,42 @@ You can [download](https://github.com/teserakt-io/e4go/releases) the binary for Our key generator relies on Go's `crypto/rand` package, which guarantees cryptographically secure randomness across various platforms. +### Bindings + +#### Android + +Latest bindings for Android can be downloaded from the [release page](https://github.com/teserakt-io/e4go/releases). +On an environment having an Android SDK and NDK available, an Android AAR package can be generated invoking the following script: + +```bash +./scripts/android_bindings.sh +``` + +This will generate: + +- `dist/bindings/android/e4.aar`: the Android package, containing compiled Java class and native libraries for most common architectures +- `dist/bindings/android/e4-sources.jar`: the Java source files + +After importing the AAR in your project, E4 client can be created and invoked +in a similar way than the Go version, for example using Kotlin: + +```kotlin +import io.teserakt.e4.* +import io.teserakt.crypto.* + +val cfg = SymNameAndPassword() +cfg.name = "deviceXYZ" +cfg.password = "secretForDeviceXYZ" + +val client = E4.newClient(cfg, cacheDir.path + "deviceXYZ.json") + +// From here, messages can be protected / unprotected : +val topic = "/deviceXYZ/data"; +val protectedMessage = client.protectMessage("Hello".toByteArray(Charsets.UTF_8), topic) +val unprotectedMessage = client.unprotect(protectedMessage, topic) +``` + + ## Contributing Before contributing, please read our [CONTRIBUTING](./CONTRIBUTING.md) guide. diff --git a/client.go b/client.go index 503aa4e..25025bd 100644 --- a/client.go +++ b/client.go @@ -147,7 +147,7 @@ type SymNameAndPassword struct { // from an ID, an ed25519 private key, and a curve25519 public key. type PubIDAndKey struct { ID []byte - Key ed25519.PrivateKey + Key e4crypto.Ed25519PrivateKey C2PubKey e4crypto.Curve25519PublicKey } @@ -232,13 +232,13 @@ func (np *PubNameAndPassword) genNewClient(persistStatePath string) (Client, err } // PubKey returns the ed25519.PublicKey derived from the password -func (np *PubNameAndPassword) PubKey() (ed25519.PublicKey, error) { +func (np *PubNameAndPassword) PubKey() (e4crypto.Ed25519PublicKey, error) { key, err := e4crypto.Ed25519PrivateKeyFromPassword(np.Password) if err != nil { return nil, fmt.Errorf("failed to create ed25519 key from password: %v", err) } - edKey, ok := key.Public().(ed25519.PublicKey) + edKey, ok := ed25519.PrivateKey(key).Public().(ed25519.PublicKey) if !ok { return nil, errors.New("failed to cast key to ed25519.PublicKey") } diff --git a/client_test.go b/client_test.go index 86bb36b..c823d58 100644 --- a/client_test.go +++ b/client_test.go @@ -310,7 +310,8 @@ func TestProtectUnprotectCommandsPubKey(t *testing.T) { t.Fatalf("Failed to generate ed25519 key: %v", err) } - c2PublicCurveKey, c2PrivateCurveKey, err := e4crypto.RandomCurve25519Keys() + c2PrivateCurveKey := e4crypto.RandomKey() + c2PublicCurveKey, err := curve25519.X25519(c2PrivateCurveKey, curve25519.Basepoint) if err != nil { t.Fatalf("Failed to generate curve25519 keys: %v", err) } @@ -635,7 +636,7 @@ func TestCommandsSymClient(t *testing.T) { assertClientTopicKey(t, true, c, topicHash, topicKey) - removeTopicCmd := []byte{RemoveTopic.ToByte()} + removeTopicCmd := []byte{RemoveTopic} removeTopicCmd = append(removeTopicCmd, topicHash...) protectedRemoveTopicCmd, err := e4crypto.ProtectSymKey(removeTopicCmd, clientKey) @@ -712,7 +713,7 @@ func TestCommandsSymClient(t *testing.T) { } // Reset topics - resetTopicCmd := []byte{ResetTopics.ToByte()} + resetTopicCmd := []byte{ResetTopics} protectedResetCmd, err := e4crypto.ProtectSymKey(resetTopicCmd, clientKey) if err != nil { t.Fatalf("Failed to protect command: %v", err) @@ -737,7 +738,7 @@ func TestCommandsSymClient(t *testing.T) { assertClientTopicKey(t, false, c, topicHash, topicKey) // SetIDKey - setIDKeyCmd := []byte{SetIDKey.ToByte()} + setIDKeyCmd := []byte{SetIDKey} newClientKey := e4crypto.RandomKey() setIDKeyCmd = append(setIDKeyCmd, newClientKey...) @@ -768,7 +769,7 @@ func TestCommandsSymClient(t *testing.T) { t.Fatal("Expected an error with a command protected with old key") } - setPubKeyCmd := []byte{SetPubKey.ToByte()} + setPubKeyCmd := []byte{SetPubKey} pubKey, _, err := ed25519.GenerateKey(nil) if err != nil { t.Fatalf("Failed to generate pubkey: %v", err) @@ -796,7 +797,7 @@ func TestCommandsSymClient(t *testing.T) { } // RemovePubKey - removePubKeyCmd := []byte{RemovePubKey.ToByte()} + removePubKeyCmd := []byte{RemovePubKey} removePubKeyCmd = append(removePubKeyCmd, pubKeyID...) protectedRemovePubKeyCmd, err := e4crypto.ProtectSymKey(removePubKeyCmd, newClientKey) @@ -818,7 +819,7 @@ func TestCommandsSymClient(t *testing.T) { } // ResetPubKeys - resetPubKeyCmd := []byte{ResetPubKeys.ToByte()} + resetPubKeyCmd := []byte{ResetPubKeys} protectedResetPubKeyCmd, err := e4crypto.ProtectSymKey(resetPubKeyCmd, newClientKey) if err != nil { diff --git a/cmd/e4keygen/e4keygen.go b/cmd/e4keygen/e4keygen.go index 0b67cea..364afde 100644 --- a/cmd/e4keygen/e4keygen.go +++ b/cmd/e4keygen/e4keygen.go @@ -20,6 +20,7 @@ import ( "log" "os" + "golang.org/x/crypto/curve25519" "golang.org/x/crypto/ed25519" e4crypto "github.com/teserakt-io/e4go/crypto" @@ -61,15 +62,16 @@ func main() { case KeyTypeEd25519: pubKey, privKey, err = ed25519.GenerateKey(nil) if err != nil { - log.Fatalf("failed to generate ed25519 key: %v\n", err) + log.Fatalf("Failed to generate ed25519 key: %v\n", err) } case KeyTypeCurve25519: - pubKey, privKey, err = e4crypto.RandomCurve25519Keys() + privKey = e4crypto.RandomKey() + pubKey, err = curve25519.X25519(privKey, curve25519.Basepoint) if err != nil { - log.Fatalf("failed to generate curve25519 key: %v\n", err) + log.Fatalf("Failed to generate curve25519 key: %v\n", err) } default: - log.Fatalf("unknown key type: %s\n", keyType) + log.Fatalf("Unknown key type: %s\n", keyType) } if err := writeKey(privKey, pubKey, out, force); err != nil { diff --git a/commands.go b/commands.go index d2de2d8..d905642 100644 --- a/commands.go +++ b/commands.go @@ -23,16 +23,11 @@ import ( e4crypto "github.com/teserakt-io/e4go/crypto" ) -// Command is a command sent by C2 to a client. This is a sequence of bytes, starting from a Command, followed by the command arguments. -// Such command message must then be protected using the client key, before being passed to the client's Unprotect() method. The command will -// then be unprotected, and processed. -type Command int - // List of supported commands const ( // RemoveTopic command allows to remove a topic key from the client. // It expects a topic hash as argument - RemoveTopic Command = iota + RemoveTopic byte = iota // ResetTopics allows to clear out all the topics on a client. // It doesn't have any argument ResetTopics @@ -54,7 +49,7 @@ const ( // UnknownCommand must stay the last element. It's used to // know if a Command is out of range - UnknownCommand + UnknownCommand = 0xFF ) var ( @@ -62,21 +57,12 @@ var ( ErrInvalidCommand = errors.New("invalid command") ) -// ToByte converts a command into its byte representation -// A value of 255 is returned when the command is out of range -func (c Command) ToByte() byte { - if c < RemoveTopic || c >= UnknownCommand { - return 255 - } - return byte(c) -} - // processCommand will attempt to parse given command // and extract arguments to call expected Client method func processCommand(client Client, payload []byte) error { cmd, blob := payload[0], payload[1:] - switch Command(cmd) { + switch cmd { case RemoveTopic: if len(blob) != e4crypto.HashLen { return errors.New("invalid RemoveTopic length") @@ -131,14 +117,14 @@ func CmdRemoveTopic(topic string) ([]byte, error) { return nil, errors.New("topic must not be empty") } - cmd := append([]byte{RemoveTopic.ToByte()}, e4crypto.HashTopic(topic)...) + cmd := append([]byte{RemoveTopic}, e4crypto.HashTopic(topic)...) return cmd, nil } // CmdResetTopics creates a command to remove all topic keys stored on the client func CmdResetTopics() ([]byte, error) { - return []byte{ResetTopics.ToByte()}, nil + return []byte{ResetTopics}, nil } // CmdSetIDKey creates a command to set the client private key to the given key @@ -147,7 +133,7 @@ func CmdSetIDKey(key []byte) ([]byte, error) { return nil, fmt.Errorf("invalid key length, got %d, wanted %d", keyLen, e4crypto.KeyLen) } - cmd := append([]byte{SetIDKey.ToByte()}, key...) + cmd := append([]byte{SetIDKey}, key...) return cmd, nil } @@ -163,7 +149,7 @@ func CmdSetTopicKey(topicKey []byte, topic string) ([]byte, error) { return nil, errors.New("topic must not be empty") } - cmd := append([]byte{SetTopicKey.ToByte()}, topicKey...) + cmd := append([]byte{SetTopicKey}, topicKey...) cmd = append(cmd, e4crypto.HashTopic(topic)...) return cmd, nil @@ -175,19 +161,19 @@ func CmdRemovePubKey(name string) ([]byte, error) { return nil, errors.New("name must not be empty") } - cmd := append([]byte{RemovePubKey.ToByte()}, e4crypto.HashIDAlias(name)...) + cmd := append([]byte{RemovePubKey}, e4crypto.HashIDAlias(name)...) return cmd, nil } // CmdResetPubKeys creates a command to removes all public keys from the client func CmdResetPubKeys() ([]byte, error) { - return []byte{ResetPubKeys.ToByte()}, nil + return []byte{ResetPubKeys}, nil } // CmdSetPubKey creates a command to set a given public key, // identified by given name on the client -func CmdSetPubKey(pubKey ed25519.PublicKey, name string) ([]byte, error) { +func CmdSetPubKey(pubKey e4crypto.Ed25519PublicKey, name string) ([]byte, error) { if g, w := len(pubKey), ed25519.PublicKeySize; g != w { return nil, fmt.Errorf("invalid public key length, got %d, wanted %d", g, w) } @@ -196,7 +182,7 @@ func CmdSetPubKey(pubKey ed25519.PublicKey, name string) ([]byte, error) { return nil, errors.New("name must not be empty") } - cmd := append([]byte{SetPubKey.ToByte()}, pubKey...) + cmd := append([]byte{SetPubKey}, pubKey...) cmd = append(cmd, e4crypto.HashIDAlias(name)...) return cmd, nil diff --git a/commands_test.go b/commands_test.go index 2f2ed95..dcd87c3 100644 --- a/commands_test.go +++ b/commands_test.go @@ -64,7 +64,7 @@ func TestCmdRemoveTopic(t *testing.T) { t.Fatalf("invalid command length, got %d, wanted %d", got, want) } - expectedCmd := append([]byte{RemoveTopic.ToByte()}, e4crypto.HashTopic(topic)...) + expectedCmd := append([]byte{RemoveTopic}, e4crypto.HashTopic(topic)...) if !bytes.Equal(cmd, expectedCmd) { t.Fatalf("invalid command, got %v, wanted %v", cmd, expectedCmd) } @@ -82,7 +82,7 @@ func TestCmdResetTopics(t *testing.T) { t.Fatalf("invalid command length, got %d, wanted %d", got, want) } - expectedCmd := []byte{ResetTopics.ToByte()} + expectedCmd := []byte{ResetTopics} if !bytes.Equal(cmd, expectedCmd) { t.Fatalf("invalid command, got %v, wanted %v", cmd, expectedCmd) } @@ -110,7 +110,7 @@ func TestCmdSetIDKey(t *testing.T) { t.Fatalf("invalid command length, got %d, wanted %d", got, want) } - expectedCmd := append([]byte{SetIDKey.ToByte()}, expectedKey...) + expectedCmd := append([]byte{SetIDKey}, expectedKey...) if !bytes.Equal(cmd, expectedCmd) { t.Fatalf("invalid command, got %v, wanted %v", cmd, expectedCmd) } @@ -149,7 +149,7 @@ func TestCmdSetTopicKey(t *testing.T) { t.Fatalf("invalid command length, got %d, wanted %d", got, want) } - expectedCmd := append([]byte{SetTopicKey.ToByte()}, expectedKey...) + expectedCmd := append([]byte{SetTopicKey}, expectedKey...) expectedCmd = append(expectedCmd, e4crypto.HashTopic(expectedTopic)...) if !bytes.Equal(cmd, expectedCmd) { t.Fatalf("invalid command, got %v, wanted %v", cmd, expectedCmd) @@ -178,7 +178,7 @@ func TestCmdRemovePubKey(t *testing.T) { t.Fatalf("invalid command length, got %d, wanted %d", got, want) } - expectedCmd := append([]byte{RemovePubKey.ToByte()}, e4crypto.HashIDAlias(expectedName)...) + expectedCmd := append([]byte{RemovePubKey}, e4crypto.HashIDAlias(expectedName)...) if !bytes.Equal(cmd, expectedCmd) { t.Fatalf("invalid command, got %v, wanted %v", cmd, expectedCmd) } @@ -196,7 +196,7 @@ func TestCmdResetPubKeys(t *testing.T) { t.Fatalf("invalid command length, got %d, wanted %d", got, want) } - expectedCmd := []byte{ResetPubKeys.ToByte()} + expectedCmd := []byte{ResetPubKeys} if !bytes.Equal(cmd, expectedCmd) { t.Fatalf("invalid command, got %v, wanted %v", cmd, expectedCmd) } @@ -243,7 +243,7 @@ func TestCmdSetPubKey(t *testing.T) { t.Fatalf("invalid command length, got %d, wanted %d", got, want) } - expectedCmd := append([]byte{SetPubKey.ToByte()}, expectedKey...) + expectedCmd := append([]byte{SetPubKey}, expectedKey...) expectedCmd = append(expectedCmd, e4crypto.HashIDAlias(expectedName)...) if !bytes.Equal(cmd, expectedCmd) { t.Fatalf("invalid command, got %v, wanted %v", cmd, expectedCmd) @@ -253,8 +253,8 @@ func TestCmdSetPubKey(t *testing.T) { func TestToByte(t *testing.T) { t.Run("ToByte() returns 255 for out of range commands", func(t *testing.T) { - if UnknownCommand.ToByte() != 255 { - t.Fatalf("expected unknown command byte to be %d, got %d", 255, UnknownCommand.ToByte()) + if UnknownCommand != 255 { + t.Fatalf("expected unknown command byte to be %d, got %d", 255, UnknownCommand) } }) } diff --git a/crypto/crypto.go b/crypto/crypto.go index 418ac5a..d9289e8 100644 --- a/crypto/crypto.go +++ b/crypto/crypto.go @@ -25,7 +25,6 @@ import ( "github.com/agl/ed25519/extra25519" miscreant "github.com/miscreant/miscreant.go" "golang.org/x/crypto/argon2" - "golang.org/x/crypto/curve25519" "golang.org/x/crypto/ed25519" ) @@ -46,11 +45,17 @@ var ( ErrInvalidTimestamp = errors.New("invalid timestamp") ) -// Curve25519PublicKey defines a type for curve 25519 public keys -type Curve25519PublicKey []byte +// Ed25519PublicKey defines an alias for Ed25519 public keys +type Ed25519PublicKey = []byte -// Curve25519PrivateKey defines a type for curve 25519 private keys -type Curve25519PrivateKey []byte +// Ed25519PrivateKey defines an alias for Ed25519 private keys +type Ed25519PrivateKey = []byte + +// Curve25519PublicKey defines an alias for curve 25519 public keys +type Curve25519PublicKey = []byte + +// Curve25519PrivateKey defines an alias for curve 25519 private keys +type Curve25519PrivateKey = []byte // Encrypt creates an authenticated ciphertext func Encrypt(key, ad, pt []byte) ([]byte, error) { @@ -92,7 +97,7 @@ func Decrypt(key, ad, ct []byte) ([]byte, error) { // Sign will sign the given payload using the given privateKey, // producing an output composed of: timestamp + signedID + payload + signature -func Sign(signerID []byte, privateKey ed25519.PrivateKey, timestamp []byte, payload []byte) ([]byte, error) { +func Sign(signerID []byte, privateKey Ed25519PrivateKey, timestamp []byte, payload []byte) ([]byte, error) { if len(signerID) != IDLen { return nil, ErrInvalidSignerID } @@ -178,17 +183,6 @@ func RandomKey() []byte { return key } -// RandomCurve25519Keys generates Curve25519 public and private keys -func RandomCurve25519Keys() (Curve25519PublicKey, Curve25519PrivateKey, error) { - privateKey := RandomKey() - publicKey, err := curve25519.X25519(privateKey, curve25519.Basepoint) - if err != nil { - return nil, nil, err - } - - return publicKey, privateKey, nil -} - // RandomID generates a random IDLen-byte ID func RandomID() []byte { id := make([]byte, IDLen) @@ -212,7 +206,7 @@ func RandomDelta16() uint16 { } // Ed25519PrivateKeyFromPassword creates a ed25519.PrivateKey from a password -func Ed25519PrivateKeyFromPassword(password string) (ed25519.PrivateKey, error) { +func Ed25519PrivateKeyFromPassword(password string) (Ed25519PrivateKey, error) { if err := ValidatePassword(password); err != nil { return nil, fmt.Errorf("invalid password: %v", err) } @@ -221,8 +215,8 @@ func Ed25519PrivateKeyFromPassword(password string) (ed25519.PrivateKey, error) return ed25519.NewKeyFromSeed(seed), nil } -// PublicEd25519KeyToCurve25519 convert an ed25519.PublicKey to a curve25519 public key. -func PublicEd25519KeyToCurve25519(edPubKey ed25519.PublicKey) Curve25519PublicKey { +// PublicEd25519KeyToCurve25519 convert an Ed25519PublicKey to a Curve25519PublicKey. +func PublicEd25519KeyToCurve25519(edPubKey Ed25519PublicKey) Curve25519PublicKey { var edPk [ed25519.PublicKeySize]byte var curveKey [Curve25519PubKeyLen]byte copy(edPk[:], edPubKey) @@ -233,8 +227,8 @@ func PublicEd25519KeyToCurve25519(edPubKey ed25519.PublicKey) Curve25519PublicKe return curveKey[:] } -// PrivateEd25519KeyToCurve25519 convert an ed25519.PrivateKey to a curve25519 private key. -func PrivateEd25519KeyToCurve25519(edPrivKey ed25519.PrivateKey) Curve25519PrivateKey { +// PrivateEd25519KeyToCurve25519 convert an Ed25519PrivateKey to a Curve25519PrivateKey. +func PrivateEd25519KeyToCurve25519(edPrivKey Ed25519PrivateKey) Curve25519PrivateKey { var edSk [ed25519.PrivateKeySize]byte var curveKey [Curve25519PrivKeyLen]byte copy(edSk[:], edPrivKey) diff --git a/example_test.go b/example_test.go index cc0651b..459b89f 100644 --- a/example_test.go +++ b/example_test.go @@ -19,6 +19,7 @@ import ( e4 "github.com/teserakt-io/e4go" e4crypto "github.com/teserakt-io/e4go/crypto" + "golang.org/x/crypto/curve25519" ) func ExampleNewClient_symIDAndKey() { @@ -55,7 +56,7 @@ func ExampleNewClient_pubIDAndKey() { panic(err) } - c2PubKey, _, err := e4crypto.RandomCurve25519Keys() + c2PubKey, err := curve25519.X25519(e4crypto.RandomKey(), curve25519.Basepoint) if err != nil { panic(err) } @@ -79,7 +80,7 @@ func ExampleNewClient_pubIDAndKey() { } func ExampleNewClient_pubNameAndPassword() { - c2PubKey, _, err := e4crypto.RandomCurve25519Keys() + c2PubKey, err := curve25519.X25519(e4crypto.RandomKey(), curve25519.Basepoint) if err != nil { panic(err) } diff --git a/go.mod b/go.mod index 2dee625..8e9e54a 100644 --- a/go.mod +++ b/go.mod @@ -8,4 +8,5 @@ require ( github.com/marcusolsson/tui-go v0.4.0 github.com/miscreant/miscreant.go v0.0.0-20190903041724-6bebe170cbaf golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413 + golang.org/x/mobile v0.0.0-20200113190325-b9f03b3fa33c // indirect ) diff --git a/go.sum b/go.sum index 9eb8ae4..1692d3e 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,4 @@ +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/agl/ed25519 v0.0.0-20170116200512-5312a6153412 h1:w1UutsfOrms1J05zt7ISrnJIXKzwaspym5BTKGx93EI= github.com/agl/ed25519 v0.0.0-20170116200512-5312a6153412/go.mod h1:WPjqKcmVOxf0XSf3YxCJs6N6AOSrOx3obionmG7T0y0= github.com/eclipse/paho.mqtt.golang v1.2.0 h1:1F8mhG9+aO5/xpdtFkW4SxOJB67ukuDC3t2y2qayIX0= @@ -27,14 +28,33 @@ github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1 github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c h1:Ho+uVpkel/udgjbwB5Lktg9BtvJSh2DT0Hi6LPSyI2w= github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413 h1:ULYEB3JvPRE/IfO+9uO7vKV/xzVTO7XPAwm8xbf4w2g= golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d h1:2+ZP7EfsZV7Vvmx3TIqSlSzATMkTAKqM14YGFPoSKjI= +golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56/go.mod h1:JhuoJpWY28nO4Vef9tZUw9qufEGTyX1+7lmHxV5q5G4= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20200113190325-b9f03b3fa33c h1:MT6lzujeOnLJHWALb47GdTakWeELuNqH32ND0UV+AJs= +golang.org/x/mobile v0.0.0-20200113190325-b9f03b3fa33c/go.mod h1:xVnulspMBrznVIwB4CQrGc712u7ETbNKUJ+GCqGLaEc= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= +golang.org/x/mod v0.1.1-0.20191209134235-331c550502dd/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3 h1:0GoQqolDA55aaLxZyTzK/Y2ePZzZTUrRacwib7cNsYQ= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e h1:aZzprAO9/8oim3qStq3wc1Xuxx4QmAGriC4VU4ojemQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/DATA-DOG/go-sqlmock.v1 v1.3.0 h1:FVCohIoYO7IJoDDVpV2pdq7SgrMH6wHnuTyrdrxJNoY= gopkg.in/DATA-DOG/go-sqlmock.v1 v1.3.0/go.mod h1:OdE7CF6DbADk7lN8LIKRzRJTTZXIjtWgA5THM5lhBAw= diff --git a/keys/publickey_test.go b/keys/publickey_test.go index e5eaa3a..5d77549 100644 --- a/keys/publickey_test.go +++ b/keys/publickey_test.go @@ -186,7 +186,8 @@ func TestPubKeyMaterialUnprotectCommand(t *testing.T) { t.Fatalf("Failed to generate ed25519 keys: %v", err) } - c2PublicCurveKey, c2PrivateCurveKey, err := e4crypto.RandomCurve25519Keys() + c2PrivateCurveKey := e4crypto.RandomKey() + c2PublicCurveKey, err := curve25519.X25519(c2PrivateCurveKey, curve25519.Basepoint) if err != nil { t.Fatalf("Failed to generate curve25519 keys: %v", err) } diff --git a/scripts/android_bindings.sh b/scripts/android_bindings.sh new file mode 100755 index 0000000..f01ac0c --- /dev/null +++ b/scripts/android_bindings.sh @@ -0,0 +1,16 @@ +#!/bin/bash +# Build Android bindings +# These two environment variable are required: +# export ANDROID_HOME=~/Android/Sdk/ +# export ANDROID_NDK_HOME=~/Android/Sdk/ndk/21.0.6113669/ +# (These are the default paths where Android Studio is installing the SDK and NDK, the version might need to be adjusted depending on your setup) + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" + +OUTDIR="${DIR}/../dist/bindings/android" +# List of packages to include in the generated bindings. (ie: keys is not needed) +INCLUDE_GO_PACKAGES="" + +mkdir -p "${OUTDIR}" 2>/dev/null + +gomobile bind -v -target android -o "${OUTDIR}/e4.aar" -javapkg io.teserakt ${DIR}/../ ${DIR}/../crypto