Add sym key
This commit is contained in:
parent
3a07939b01
commit
7c4abdbb8c
@ -1,10 +1,11 @@
|
||||
package aclrecordproto
|
||||
|
||||
import (
|
||||
"github.com/anytypeio/any-sync/util/crypto"
|
||||
"github.com/anytypeio/any-sync/util/keys/symmetric"
|
||||
)
|
||||
|
||||
func AclReadKeyDerive(signKey []byte, encKey []byte) (*symmetric.Key, error) {
|
||||
func AclReadKeyDerive(signKey []byte, encKey []byte) (*crypto.AESKey, error) {
|
||||
concBuf := make([]byte, 0, len(signKey)+len(encKey))
|
||||
concBuf = append(concBuf, signKey...)
|
||||
concBuf = append(concBuf, encKey...)
|
||||
|
||||
@ -5,7 +5,6 @@ import (
|
||||
"github.com/anytypeio/any-sync/commonspace/object/keychain"
|
||||
"github.com/anytypeio/any-sync/util/cidutil"
|
||||
"github.com/anytypeio/any-sync/util/crypto"
|
||||
"github.com/anytypeio/any-sync/util/keys/symmetric"
|
||||
"github.com/gogo/protobuf/proto"
|
||||
"time"
|
||||
)
|
||||
@ -37,7 +36,7 @@ func (a *aclRecordBuilder) BuildUserJoin(acceptPrivKeyBytes []byte, encSymKeyByt
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
encSymKey, err := symmetric.FromBytes(encSymKeyBytes)
|
||||
encSymKey, err := crypto.UnmarshallAESKey(encSymKeyBytes)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
@ -13,7 +13,6 @@ import (
|
||||
"github.com/anytypeio/any-sync/util/keys"
|
||||
"github.com/anytypeio/any-sync/util/keys/asymmetric/encryptionkey"
|
||||
"github.com/anytypeio/any-sync/util/keys/asymmetric/signingkey"
|
||||
"github.com/anytypeio/any-sync/util/keys/symmetric"
|
||||
"github.com/gogo/protobuf/proto"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
@ -44,7 +43,7 @@ type UserPermissionPair struct {
|
||||
type AclState struct {
|
||||
id string
|
||||
currentReadKeyHash uint64
|
||||
userReadKeys map[uint64]*symmetric.Key
|
||||
userReadKeys map[uint64]*crypto.AESKey
|
||||
userStates map[string]*aclrecordproto.AclUserState
|
||||
userInvites map[string]*aclrecordproto.AclUserInvite
|
||||
encryptionKey encryptionkey.PrivKey
|
||||
@ -71,7 +70,7 @@ func newAclStateWithKeys(
|
||||
identity: string(identity),
|
||||
signingKey: signingKey,
|
||||
encryptionKey: encryptionKey,
|
||||
userReadKeys: make(map[uint64]*symmetric.Key),
|
||||
userReadKeys: make(map[uint64]*crypto.AESKey),
|
||||
userStates: make(map[string]*aclrecordproto.AclUserState),
|
||||
userInvites: make(map[string]*aclrecordproto.AclUserInvite),
|
||||
permissionsAtRecord: make(map[string][]UserPermissionPair),
|
||||
@ -81,7 +80,7 @@ func newAclStateWithKeys(
|
||||
func newAclState(id string) *AclState {
|
||||
return &AclState{
|
||||
id: id,
|
||||
userReadKeys: make(map[uint64]*symmetric.Key),
|
||||
userReadKeys: make(map[uint64]*crypto.AESKey),
|
||||
userStates: make(map[string]*aclrecordproto.AclUserState),
|
||||
userInvites: make(map[string]*aclrecordproto.AclUserInvite),
|
||||
permissionsAtRecord: make(map[string][]UserPermissionPair),
|
||||
@ -92,7 +91,7 @@ func (st *AclState) CurrentReadKeyHash() uint64 {
|
||||
return st.currentReadKeyHash
|
||||
}
|
||||
|
||||
func (st *AclState) CurrentReadKey() (*symmetric.Key, error) {
|
||||
func (st *AclState) CurrentReadKey() (*crypto.AESKey, error) {
|
||||
key, exists := st.userReadKeys[st.currentReadKeyHash]
|
||||
if !exists {
|
||||
return nil, ErrNoReadKey
|
||||
@ -100,7 +99,7 @@ func (st *AclState) CurrentReadKey() (*symmetric.Key, error) {
|
||||
return key, nil
|
||||
}
|
||||
|
||||
func (st *AclState) UserReadKeys() map[uint64]*symmetric.Key {
|
||||
func (st *AclState) UserReadKeys() map[uint64]*crypto.AESKey {
|
||||
return st.userReadKeys
|
||||
}
|
||||
|
||||
@ -195,7 +194,7 @@ func (st *AclState) applyRoot(root *aclrecordproto.AclRoot) (err error) {
|
||||
}
|
||||
|
||||
func (st *AclState) saveReadKeyFromRoot(root *aclrecordproto.AclRoot) (err error) {
|
||||
var readKey *symmetric.Key
|
||||
var readKey *crypto.AESKey
|
||||
if len(root.GetDerivationScheme()) != 0 {
|
||||
var encPrivKey []byte
|
||||
encPrivKey, err = st.encryptionKey.Raw()
|
||||
@ -401,13 +400,13 @@ func (st *AclState) applyUserRemove(ch *aclrecordproto.AclUserRemove) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (st *AclState) decryptReadKeyAndHash(msg []byte) (*symmetric.Key, uint64, error) {
|
||||
func (st *AclState) decryptReadKeyAndHash(msg []byte) (*crypto.AESKey, uint64, error) {
|
||||
decrypted, err := st.encryptionKey.Decrypt(msg)
|
||||
if err != nil {
|
||||
return nil, 0, ErrFailedToDecrypt
|
||||
}
|
||||
|
||||
key, err := symmetric.FromBytes(decrypted)
|
||||
key, err := crypto.UnmarshallAESKey(decrypted)
|
||||
if err != nil {
|
||||
return nil, 0, ErrFailedToDecrypt
|
||||
}
|
||||
|
||||
@ -6,14 +6,13 @@ import (
|
||||
"github.com/anytypeio/any-sync/util/keys"
|
||||
"github.com/anytypeio/any-sync/util/keys/asymmetric/encryptionkey"
|
||||
"github.com/anytypeio/any-sync/util/keys/asymmetric/signingkey"
|
||||
"github.com/anytypeio/any-sync/util/keys/symmetric"
|
||||
"hash/fnv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type SymKey struct {
|
||||
Hash uint64
|
||||
Key *symmetric.Key
|
||||
Key *crypto.AESKey
|
||||
}
|
||||
|
||||
type YAMLKeychain struct {
|
||||
@ -111,11 +110,11 @@ func (k *YAMLKeychain) AddReadKey(key *Key) {
|
||||
}
|
||||
|
||||
var (
|
||||
rkey *symmetric.Key
|
||||
rkey *crypto.AESKey
|
||||
err error
|
||||
)
|
||||
if key.Value == "generated" {
|
||||
rkey, err = symmetric.NewRandom()
|
||||
rkey, err = crypto.NewRandomAES()
|
||||
if err != nil {
|
||||
panic("should be able to generate symmetric key")
|
||||
}
|
||||
@ -127,7 +126,7 @@ func (k *YAMLKeychain) AddReadKey(key *Key) {
|
||||
panic("should be able to derive symmetric key")
|
||||
}
|
||||
} else {
|
||||
rkey, err = symmetric.FromString(key.Value)
|
||||
rkey, err = crypto.UnmarshallAESKeyString(key.Value)
|
||||
if err != nil {
|
||||
panic("should be able to parse symmetric key")
|
||||
}
|
||||
|
||||
@ -7,9 +7,9 @@ import (
|
||||
"github.com/anytypeio/any-sync/commonspace/object/acl/liststorage"
|
||||
"github.com/anytypeio/any-sync/commonspace/object/acl/testutils/yamltests"
|
||||
"github.com/anytypeio/any-sync/util/cidutil"
|
||||
"github.com/anytypeio/any-sync/util/crypto"
|
||||
"github.com/anytypeio/any-sync/util/keys/asymmetric/encryptionkey"
|
||||
"github.com/anytypeio/any-sync/util/keys/asymmetric/signingkey"
|
||||
"github.com/anytypeio/any-sync/util/keys/symmetric"
|
||||
"gopkg.in/yaml.v3"
|
||||
"io/ioutil"
|
||||
"path"
|
||||
@ -249,7 +249,7 @@ func (t *AclListStorageBuilder) encryptReadKeysWithPubKey(keys []string, encKey
|
||||
return
|
||||
}
|
||||
|
||||
func (t *AclListStorageBuilder) encryptReadKeysWithSymKey(keys []string, key *symmetric.Key) (enc [][]byte) {
|
||||
func (t *AclListStorageBuilder) encryptReadKeysWithSymKey(keys []string, key *crypto.AESKey) (enc [][]byte) {
|
||||
for _, k := range keys {
|
||||
realKey := t.keychain.GetKey(k).(*SymKey).Key.Bytes()
|
||||
res, err := key.Encrypt(realKey)
|
||||
|
||||
@ -5,8 +5,8 @@ import (
|
||||
"github.com/anytypeio/any-sync/commonspace/object/keychain"
|
||||
"github.com/anytypeio/any-sync/commonspace/object/tree/treechangeproto"
|
||||
"github.com/anytypeio/any-sync/util/cidutil"
|
||||
"github.com/anytypeio/any-sync/util/crypto"
|
||||
"github.com/anytypeio/any-sync/util/keys/asymmetric/signingkey"
|
||||
"github.com/anytypeio/any-sync/util/keys/symmetric"
|
||||
"github.com/gogo/protobuf/proto"
|
||||
"time"
|
||||
)
|
||||
@ -21,7 +21,7 @@ type BuilderContent struct {
|
||||
Identity []byte
|
||||
IsSnapshot bool
|
||||
SigningKey signingkey.PrivKey
|
||||
ReadKey *symmetric.Key
|
||||
ReadKey *crypto.AESKey
|
||||
Content []byte
|
||||
}
|
||||
|
||||
|
||||
@ -4,6 +4,7 @@ package objecttree
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"github.com/anytypeio/any-sync/util/crypto"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
@ -11,7 +12,6 @@ import (
|
||||
"github.com/anytypeio/any-sync/commonspace/object/acl/list"
|
||||
"github.com/anytypeio/any-sync/commonspace/object/tree/treechangeproto"
|
||||
"github.com/anytypeio/any-sync/commonspace/object/tree/treestorage"
|
||||
"github.com/anytypeio/any-sync/util/keys/symmetric"
|
||||
"github.com/anytypeio/any-sync/util/slice"
|
||||
)
|
||||
|
||||
@ -99,7 +99,7 @@ type objectTree struct {
|
||||
root *Change
|
||||
tree *Tree
|
||||
|
||||
keys map[uint64]*symmetric.Key
|
||||
keys map[uint64]*crypto.AESKey
|
||||
|
||||
// buffers
|
||||
difSnapshotBuf []*treechangeproto.RawTreeChangeWithId
|
||||
@ -225,7 +225,7 @@ func (ot *objectTree) prepareBuilderContent(content SignableChangeContent) (cnt
|
||||
|
||||
var (
|
||||
state = ot.aclList.AclState() // special method for own keys
|
||||
readKey *symmetric.Key
|
||||
readKey *crypto.AESKey
|
||||
readKeyHash uint64
|
||||
)
|
||||
canWrite := state.HasPermission(content.Identity, aclrecordproto.AclUserPermissions_Writer) ||
|
||||
|
||||
@ -5,8 +5,8 @@ import (
|
||||
"github.com/anytypeio/any-sync/commonspace/object/keychain"
|
||||
"github.com/anytypeio/any-sync/commonspace/object/tree/treechangeproto"
|
||||
"github.com/anytypeio/any-sync/commonspace/object/tree/treestorage"
|
||||
"github.com/anytypeio/any-sync/util/crypto"
|
||||
"github.com/anytypeio/any-sync/util/keys/asymmetric/signingkey"
|
||||
"github.com/anytypeio/any-sync/util/keys/symmetric"
|
||||
"math/rand"
|
||||
"time"
|
||||
)
|
||||
@ -189,7 +189,7 @@ func buildObjectTree(deps objectTreeDeps) (ObjectTree, error) {
|
||||
aclList: deps.aclList,
|
||||
changeBuilder: deps.changeBuilder,
|
||||
rawChangeLoader: deps.rawChangeLoader,
|
||||
keys: make(map[uint64]*symmetric.Key),
|
||||
keys: make(map[uint64]*crypto.AESKey),
|
||||
newChangesBuf: make([]*Change, 0, 10),
|
||||
difSnapshotBuf: make([]*treechangeproto.RawTreeChangeWithId, 0, 10),
|
||||
notSeenIdxBuf: make([]int, 0, 10),
|
||||
@ -225,7 +225,7 @@ func buildHistoryTree(deps objectTreeDeps, params HistoryTreeParams) (ht History
|
||||
aclList: deps.aclList,
|
||||
changeBuilder: deps.changeBuilder,
|
||||
rawChangeLoader: deps.rawChangeLoader,
|
||||
keys: make(map[uint64]*symmetric.Key),
|
||||
keys: make(map[uint64]*crypto.AESKey),
|
||||
newChangesBuf: make([]*Change, 0, 10),
|
||||
difSnapshotBuf: make([]*treechangeproto.RawTreeChangeWithId, 0, 10),
|
||||
notSeenIdxBuf: make([]int, 0, 10),
|
||||
|
||||
@ -1,12 +1,11 @@
|
||||
package symmetric
|
||||
package crypto
|
||||
|
||||
import (
|
||||
"crypto/aes"
|
||||
"crypto/cipher"
|
||||
"crypto/rand"
|
||||
"crypto/subtle"
|
||||
"fmt"
|
||||
"github.com/minio/sha256-simd"
|
||||
|
||||
mbase "github.com/multiformats/go-multibase"
|
||||
)
|
||||
|
||||
@ -18,83 +17,65 @@ const (
|
||||
KeyBytes = 32
|
||||
)
|
||||
|
||||
type Key struct {
|
||||
type AESKey struct {
|
||||
raw []byte
|
||||
}
|
||||
|
||||
func DeriveFromBytes(bytes []byte) (*Key, error) {
|
||||
bArray := sha256.Sum256(bytes)
|
||||
bSlice := bArray[:]
|
||||
return FromBytes(bSlice)
|
||||
}
|
||||
|
||||
func (k *Key) Equals(otherKey *Key) bool {
|
||||
otherRaw := otherKey.raw
|
||||
keyRaw := k.raw
|
||||
|
||||
if len(keyRaw) != len(otherRaw) {
|
||||
func (k *AESKey) Equals(key Key) bool {
|
||||
aesKey, ok := key.(*AESKey)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
for i := 0; i < len(keyRaw); i++ {
|
||||
if keyRaw[i] != otherRaw[i] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
return subtle.ConstantTimeCompare(k.raw, aesKey.raw) == 1
|
||||
}
|
||||
|
||||
func (k *Key) Raw() ([]byte, error) {
|
||||
func (k *AESKey) Raw() ([]byte, error) {
|
||||
return k.raw, nil
|
||||
}
|
||||
|
||||
// NewRandom returns a random key.
|
||||
func NewRandom() (*Key, error) {
|
||||
// NewRandomAES returns a random key.
|
||||
func NewRandomAES() (*AESKey, error) {
|
||||
raw := make([]byte, KeyBytes)
|
||||
if _, err := rand.Read(raw); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &Key{raw: raw}, nil
|
||||
return &AESKey{raw: raw}, nil
|
||||
}
|
||||
|
||||
// New returns Key if err is nil and panics otherwise.
|
||||
func New() *Key {
|
||||
k, err := NewRandom()
|
||||
// NewAES returns AESKey if err is nil and panics otherwise.
|
||||
func NewAES() *AESKey {
|
||||
k, err := NewRandomAES()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return k
|
||||
}
|
||||
|
||||
// FromBytes returns a key by decoding bytes.
|
||||
func FromBytes(k []byte) (*Key, error) {
|
||||
// UnmarshallAESKey returns a key by decoding bytes.
|
||||
func UnmarshallAESKey(k []byte) (*AESKey, error) {
|
||||
if len(k) != KeyBytes {
|
||||
return nil, fmt.Errorf("invalid key")
|
||||
}
|
||||
return &Key{raw: k}, nil
|
||||
return &AESKey{raw: k}, nil
|
||||
}
|
||||
|
||||
// FromString returns a key by decoding a base32-encoded string.
|
||||
func FromString(k string) (*Key, error) {
|
||||
// UnmarshallAESKeyString returns a key by decoding a base32-encoded string.
|
||||
func UnmarshallAESKeyString(k string) (*AESKey, error) {
|
||||
_, b, err := mbase.Decode(k)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return FromBytes(b)
|
||||
return UnmarshallAESKey(b)
|
||||
}
|
||||
|
||||
// Bytes returns raw key bytes.
|
||||
func (k *Key) Bytes() []byte {
|
||||
func (k *AESKey) Bytes() []byte {
|
||||
return k.raw
|
||||
}
|
||||
|
||||
// MarshalBinary implements BinaryMarshaler.
|
||||
func (k *Key) MarshalBinary() ([]byte, error) {
|
||||
return k.raw, nil
|
||||
}
|
||||
|
||||
// String returns the base32-encoded string representation of raw key bytes.
|
||||
func (k *Key) String() string {
|
||||
func (k *AESKey) String() string {
|
||||
str, err := mbase.Encode(mbase.Base32, k.raw)
|
||||
if err != nil {
|
||||
panic("should not error with hardcoded mbase: " + err.Error())
|
||||
@ -103,7 +84,7 @@ func (k *Key) String() string {
|
||||
}
|
||||
|
||||
// Encrypt performs AES-256 GCM encryption on plaintext.
|
||||
func (k *Key) Encrypt(plaintext []byte) ([]byte, error) {
|
||||
func (k *AESKey) Encrypt(plaintext []byte) ([]byte, error) {
|
||||
block, err := aes.NewCipher(k.raw[:KeyBytes])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -122,7 +103,7 @@ func (k *Key) Encrypt(plaintext []byte) ([]byte, error) {
|
||||
}
|
||||
|
||||
// Decrypt uses key to perform AES-256 GCM decryption on ciphertext.
|
||||
func (k *Key) Decrypt(ciphertext []byte) ([]byte, error) {
|
||||
func (k *AESKey) Decrypt(ciphertext []byte) ([]byte, error) {
|
||||
block, err := aes.NewCipher(k.raw[:KeyBytes])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -1,20 +1,14 @@
|
||||
syntax = "proto3";
|
||||
package utilcrypto;
|
||||
package crypto;
|
||||
option go_package = "util/crypto/cryptoproto";
|
||||
|
||||
enum KeyType {
|
||||
RSA = 0;
|
||||
Ed25519 = 1;
|
||||
Secp256k1 = 2;
|
||||
ECDSA = 3;
|
||||
Ed25519Public = 0;
|
||||
Ed25519Private = 1;
|
||||
AES = 2;
|
||||
}
|
||||
|
||||
message PublicKey {
|
||||
message Key {
|
||||
KeyType Type = 1;
|
||||
bytes Data = 2;
|
||||
}
|
||||
|
||||
message PrivateKey {
|
||||
KeyType Type = 1;
|
||||
bytes Data = 2;
|
||||
}
|
||||
@ -1,52 +0,0 @@
|
||||
package crypto
|
||||
|
||||
import (
|
||||
"crypto/ed25519"
|
||||
"crypto/sha512"
|
||||
"filippo.io/edwards25519"
|
||||
"golang.org/x/crypto/curve25519"
|
||||
)
|
||||
|
||||
// Ed25519PublicKeyToCurve25519 converts an Ed25519 public key to a Curve25519 public key
|
||||
func Ed25519PublicKeyToCurve25519(pk ed25519.PublicKey) []byte {
|
||||
// Unmarshalling public key into edwards curve point
|
||||
epk, err := (&edwards25519.Point{}).SetBytes(pk)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
// converting to curve25519 (see here for more details https://github.com/golang/go/issues/20504)
|
||||
return epk.BytesMontgomery()
|
||||
}
|
||||
|
||||
// ISC License
|
||||
//
|
||||
// Copyright (c) 2013-2020
|
||||
// Frank Denis <j at pureftpd dot org>
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
// https://github.com/jedisct1/libsodium/blob/master/src/libsodium/crypto_sign/ed25519/ref10/keypair.c#L69-L83
|
||||
|
||||
// Ed25519PrivateKeyToCurve25519 converts an Ed25519 private key to a Curve25519 private key
|
||||
// This code is originally taken from here https://github.com/jorrizza/ed2curve25519/blob/master/ed2curve25519.go
|
||||
func Ed25519PrivateKeyToCurve25519(pk ed25519.PrivateKey) []byte {
|
||||
h := sha512.New()
|
||||
h.Write(pk.Seed())
|
||||
out := h.Sum(nil)
|
||||
|
||||
// used in libsodium
|
||||
out[0] &= 248
|
||||
out[31] &= 127
|
||||
out[31] |= 64
|
||||
|
||||
return out[:curve25519.ScalarSize]
|
||||
}
|
||||
@ -25,7 +25,7 @@ type PrivKey interface {
|
||||
GetPublic() PubKey
|
||||
}
|
||||
|
||||
// PubKey is the public key used to verify the signatures made by SignPrivKey
|
||||
// PubKey is the public key used to verify the signatures and decrypt messages
|
||||
type PubKey interface {
|
||||
Key
|
||||
|
||||
@ -35,6 +35,15 @@ type PubKey interface {
|
||||
Verify(data []byte, sig []byte) (bool, error)
|
||||
}
|
||||
|
||||
type SymKey interface {
|
||||
Key
|
||||
|
||||
// Decrypt decrypts the message and returns the result
|
||||
Decrypt(message []byte) ([]byte, error)
|
||||
// Encrypt encrypts the message and returns the result
|
||||
Encrypt(message []byte) ([]byte, error)
|
||||
}
|
||||
|
||||
func KeyEquals(k1, k2 Key) bool {
|
||||
a, err := k1.Raw()
|
||||
if err != nil {
|
||||
|
||||
@ -1,14 +1,62 @@
|
||||
package crypto
|
||||
|
||||
import (
|
||||
"crypto/ed25519"
|
||||
"crypto/rand"
|
||||
"crypto/sha512"
|
||||
"errors"
|
||||
"filippo.io/edwards25519"
|
||||
"golang.org/x/crypto/blake2b"
|
||||
"golang.org/x/crypto/curve25519"
|
||||
"golang.org/x/crypto/nacl/box"
|
||||
)
|
||||
|
||||
var ErrX25519DecryptionFailed = errors.New("failed decryption with x25519 key")
|
||||
|
||||
// Ed25519PublicKeyToCurve25519 converts an Ed25519 public key to a Curve25519 public key
|
||||
func Ed25519PublicKeyToCurve25519(pk ed25519.PublicKey) []byte {
|
||||
// Unmarshalling public key into edwards curve point
|
||||
epk, err := (&edwards25519.Point{}).SetBytes(pk)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
// converting to curve25519 (see here for more details https://github.com/golang/go/issues/20504)
|
||||
return epk.BytesMontgomery()
|
||||
}
|
||||
|
||||
// ISC License
|
||||
//
|
||||
// Copyright (c) 2013-2020
|
||||
// Frank Denis <j at pureftpd dot org>
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
// https://github.com/jedisct1/libsodium/blob/master/src/libsodium/crypto_sign/ed25519/ref10/keypair.c#L69-L83
|
||||
|
||||
// Ed25519PrivateKeyToCurve25519 converts an Ed25519 private key to a Curve25519 private key
|
||||
// This code is originally taken from here https://github.com/jorrizza/ed2curve25519/blob/master/ed2curve25519.go
|
||||
func Ed25519PrivateKeyToCurve25519(pk ed25519.PrivateKey) []byte {
|
||||
h := sha512.New()
|
||||
h.Write(pk.Seed())
|
||||
out := h.Sum(nil)
|
||||
|
||||
// used in libsodium
|
||||
out[0] &= 248
|
||||
out[31] &= 127
|
||||
out[31] |= 64
|
||||
|
||||
return out[:curve25519.ScalarSize]
|
||||
}
|
||||
|
||||
// EncryptX25519 takes a x25519 public key and encrypts the message
|
||||
func EncryptX25519(pubKey *[32]byte, msg []byte) []byte {
|
||||
// see discussion here https://github.com/golang/go/issues/29128
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user