github.com/trustbloc/kms-go@v1.1.2/util/cryptoutil/utils.go (about) 1 /* 2 Copyright SecureKey Technologies Inc. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package cryptoutil 8 9 import ( 10 "crypto/ed25519" 11 "encoding/binary" 12 "errors" 13 "fmt" 14 15 "github.com/teserakt-io/golang-ed25519/extra25519" 16 chacha "golang.org/x/crypto/chacha20poly1305" 17 "golang.org/x/crypto/curve25519" 18 ) 19 20 // DeriveECDHX25519 does X25519 ECDH using fromPrivKey and toPubKey. 21 func DeriveECDHX25519(fromPrivKey, toPubKey *[chacha.KeySize]byte) ([]byte, error) { 22 if fromPrivKey == nil || toPubKey == nil { 23 return nil, errors.New("deriveECDHX25519: invalid key") 24 } 25 26 // do ScalarMult of the sender's private key with the recipient key to get a derived Z point (ECDH) 27 z, err := curve25519.X25519(fromPrivKey[:], toPubKey[:]) 28 if err != nil { 29 return nil, fmt.Errorf("deriveECDHX25519: %w", err) 30 } 31 32 return z, nil 33 } 34 35 // LengthPrefix array with a bigEndian uint32 value of array's length. 36 func LengthPrefix(array []byte) []byte { 37 const prefixLen = 4 38 39 arrInfo := make([]byte, prefixLen+len(array)) 40 binary.BigEndian.PutUint32(arrInfo, uint32(len(array))) 41 copy(arrInfo[prefixLen:], array) 42 43 return arrInfo 44 } 45 46 // Curve25519KeySize number of bytes in a Curve25519 public or private key. 47 const Curve25519KeySize = 32 48 49 // NonceSize size of a nonce used by Box encryption (Xchacha20Poly1305). 50 const NonceSize = 24 51 52 // PublicEd25519toCurve25519 takes an Ed25519 public key and provides the corresponding Curve25519 public key 53 // This function wraps PublicKeyToCurve25519 from Adam Langley's ed25519 repo: https://github.com/agl/ed25519 now 54 // moved to https://github.com/teserakt-io/golang-ed25519 55 func PublicEd25519toCurve25519(pub []byte) ([]byte, error) { 56 if len(pub) == 0 { 57 return nil, errors.New("public key is nil") 58 } 59 60 if len(pub) != ed25519.PublicKeySize { 61 return nil, fmt.Errorf("%d-byte key size is invalid", len(pub)) 62 } 63 64 pkOut := new([Curve25519KeySize]byte) 65 pKIn := new([Curve25519KeySize]byte) 66 copy(pKIn[:], pub) 67 68 success := extra25519.PublicKeyToCurve25519(pkOut, pKIn) 69 if !success { 70 return nil, errors.New("error converting public key") 71 } 72 73 return pkOut[:], nil 74 } 75 76 // SecretEd25519toCurve25519 converts a secret key from Ed25519 to curve25519 format 77 // This function wraps PrivateKeyToCurve25519 from Adam Langley's ed25519 repo: https://github.com/agl/ed25519 now 78 // moved to https://github.com/teserakt-io/golang-ed25519 79 func SecretEd25519toCurve25519(priv []byte) ([]byte, error) { 80 if len(priv) == 0 { 81 return nil, errors.New("private key is nil") 82 } 83 84 sKIn := new([ed25519.PrivateKeySize]byte) 85 copy(sKIn[:], priv) 86 87 sKOut := new([Curve25519KeySize]byte) 88 extra25519.PrivateKeyToCurve25519(sKOut, sKIn) 89 90 return sKOut[:], nil 91 }