diff options
Diffstat (limited to 'vendor/go.mau.fi/libsignal/util')
5 files changed, 253 insertions, 0 deletions
diff --git a/vendor/go.mau.fi/libsignal/util/bytehelper/ByteHelper.go b/vendor/go.mau.fi/libsignal/util/bytehelper/ByteHelper.go new file mode 100644 index 00000000..78f71ae4 --- /dev/null +++ b/vendor/go.mau.fi/libsignal/util/bytehelper/ByteHelper.go @@ -0,0 +1,97 @@ +package bytehelper + +import ( + "errors" +) + +// SliceToArray will convert byte slice to a 32 byte array +func SliceToArray(bytes []byte) [32]byte { + var byteArray [32]byte + copy(byteArray[:], bytes) + return byteArray +} + +// SliceToArray64 will convert byte slice to a 64 byte array +func SliceToArray64(bytes []byte) [64]byte { + var byteArray [64]byte + copy(byteArray[:], bytes) + return byteArray +} + +// ArrayToSlice will convert a 32 byte array to byte slice +func ArrayToSlice(bytes [32]byte) []byte { + return bytes[:] +} + +// ArrayToSlice64 will convert a 64 byte array to byte slice +func ArrayToSlice64(bytes [64]byte) []byte { + return bytes[:] +} + +// Split will take the given byte array and split it into half, +// with the first half being "firstLength" in size and the second +// half "secondLength" in size. +func Split(input []byte, firstLength, secondLength int) [][]byte { + parts := make([][]byte, 2) + + parts[0] = make([]byte, firstLength) + copy(parts[0], input[:firstLength]) + + parts[1] = make([]byte, secondLength) + copy(parts[1], input[firstLength:]) + + return parts +} + +// SplitThree will take the given byte array and split it into thirds, +// with the first third being "firstLength" in size, the second third +// being "secondLength" in size, and the last third being "thirdLength" +// in size. +func SplitThree(input []byte, firstLength, secondLength, thirdLength int) ([][]byte, error) { + if input == nil || firstLength < 0 || secondLength < 0 || thirdLength < 0 || + len(input) < firstLength+secondLength+thirdLength { + + return nil, errors.New("Input too small: " + string(input)) + } + + parts := make([][]byte, 3) + + parts[0] = make([]byte, firstLength) + copy(parts[0], input[:firstLength]) + + parts[1] = make([]byte, secondLength) + copy(parts[1], input[firstLength:][:secondLength]) + + parts[2] = make([]byte, thirdLength) + copy(parts[2], input[firstLength+secondLength:]) + + return parts, nil +} + +// Trim will trim the given byte array to the given length. +func Trim(input []byte, length int) []byte { + result := make([]byte, length) + copy(result, input[:length]) + + return result +} + +// Bytes5ToInt64 will convert the given byte array and offset to an int64. +func Bytes5ToInt64(bytes []byte, offset int) int64 { + + value := (int64(bytes[offset]&0xff) << 32) | + (int64(bytes[offset+1]&0xff) << 24) | + (int64(bytes[offset+2]&0xff) << 16) | + (int64(bytes[offset+3]&0xff) << 8) | + int64(bytes[offset+4]&0xff) + + return value +} + +// CopySlice returns a copy of the given bytes. +func CopySlice(bytes []byte) []byte { + cp := make([]byte, len(bytes)) + copy(cp, bytes) + + return cp +} diff --git a/vendor/go.mau.fi/libsignal/util/errorhelper/ErrorHelper.go b/vendor/go.mau.fi/libsignal/util/errorhelper/ErrorHelper.go new file mode 100644 index 00000000..b30adb0a --- /dev/null +++ b/vendor/go.mau.fi/libsignal/util/errorhelper/ErrorHelper.go @@ -0,0 +1,40 @@ +package errorhelper + +// NewMultiError returns a new MultiError object. +func NewMultiError() *MultiError { + return &MultiError{ + errors: []error{}, + } +} + +// MultiError is a structure for holding multiple errors so they +// can be checked at a later point. +type MultiError struct { + errors []error +} + +// Add will add the given error if it is not nil. +func (m *MultiError) Add(err error) { + if err != nil { + m.errors = append(m.errors, err) + } +} + +// HasErrors will return true if any non-nil errors have been +// added. +func (m *MultiError) HasErrors() bool { + if len(m.errors) > 0 { + return true + } + + return false +} + +// Error will print the first error is encountered. +func (m *MultiError) Error() string { + if !m.HasErrors() { + return "" + } + + return m.errors[0].Error() +} diff --git a/vendor/go.mau.fi/libsignal/util/keyhelper/KeyHelper.go b/vendor/go.mau.fi/libsignal/util/keyhelper/KeyHelper.go new file mode 100644 index 00000000..62481cc1 --- /dev/null +++ b/vendor/go.mau.fi/libsignal/util/keyhelper/KeyHelper.go @@ -0,0 +1,95 @@ +// Package keyhelper is based on: https://github.com/WhisperSystems/libsignal-protocol-java/blob/master/java/src/main/java/org/whispersystems/libsignal/util/KeyHelper.java +package keyhelper + +import ( + "crypto/rand" + "encoding/binary" + "time" + + "go.mau.fi/libsignal/ecc" + "go.mau.fi/libsignal/keys/identity" + "go.mau.fi/libsignal/state/record" +) + +// GenerateIdentityKeyPair generates an identity keypair used for +// signing. Clients should only do this once at install time. +func GenerateIdentityKeyPair() (*identity.KeyPair, error) { + keyPair, err := ecc.GenerateKeyPair() + if err != nil { + return nil, err + } + + publicKey := identity.NewKey(keyPair.PublicKey()) + return identity.NewKeyPair(publicKey, keyPair.PrivateKey()), nil +} + +// GeneratePreKeys generates a list of PreKeys. Client shsould do this at +// install time, and subsequently any time the list of PreKeys stored on +// the server runs low. +// +// PreKeys IDs are shorts, so they will eventually be repeated. Clients +// should store PreKeys in a circular buffer, so that they are repeated +// as infrequently as possible. +func GeneratePreKeys(start int, count int, serializer record.PreKeySerializer) ([]*record.PreKey, error) { + var preKeys []*record.PreKey + + for i := start; i <= count; i++ { + key, err := ecc.GenerateKeyPair() + if err != nil { + return nil, err + } + preKeys = append(preKeys, record.NewPreKey(uint32(i), key, serializer)) + } + + return preKeys, nil +} + +// GenerateLastResortKey will generate the last resort PreKey. Clients should +// do this only once, at install time, and durably store it for the length +// of the install. +func GenerateLastResortKey(serializer record.PreKeySerializer) (*record.PreKey, error) { + keyPair, err := ecc.GenerateKeyPair() + if err != nil { + return nil, err + } + return record.NewPreKey(0, keyPair, serializer), nil +} + +// GenerateSignedPreKey generates a signed PreKey. +func GenerateSignedPreKey(identityKeyPair *identity.KeyPair, signedPreKeyID uint32, serializer record.SignedPreKeySerializer) (*record.SignedPreKey, error) { + keyPair, err := ecc.GenerateKeyPair() + if err != nil { + return nil, err + } + signature := ecc.CalculateSignature(identityKeyPair.PrivateKey(), keyPair.PublicKey().Serialize()) + timestamp := time.Now().Unix() + + return record.NewSignedPreKey(signedPreKeyID, timestamp, keyPair, signature, serializer), nil +} + +// GenerateRegistrationID generates a registration ID. Clients should only do +// this once, at install time. +func GenerateRegistrationID() uint32 { + var n uint32 + binary.Read(rand.Reader, binary.LittleEndian, &n) + + return n +} + +//---------- Group Stuff ---------------- + +func GenerateSenderSigningKey() (*ecc.ECKeyPair, error) { + return ecc.GenerateKeyPair() +} + +func GenerateSenderKey() []byte { + randBytes := make([]byte, 32) + rand.Read(randBytes) + return randBytes +} + +func GenerateSenderKeyID() uint32 { + return GenerateRegistrationID() +} + +//---------- End Group Stuff -------------- diff --git a/vendor/go.mau.fi/libsignal/util/medium/Medium.go b/vendor/go.mau.fi/libsignal/util/medium/Medium.go new file mode 100644 index 00000000..7a509a8e --- /dev/null +++ b/vendor/go.mau.fi/libsignal/util/medium/Medium.go @@ -0,0 +1,4 @@ +package medium + +// MaxValue is the maximum possible integer value. +const MaxValue uint32 = 0xFFFFFF diff --git a/vendor/go.mau.fi/libsignal/util/optional/Integer.go b/vendor/go.mau.fi/libsignal/util/optional/Integer.go new file mode 100644 index 00000000..9e43af46 --- /dev/null +++ b/vendor/go.mau.fi/libsignal/util/optional/Integer.go @@ -0,0 +1,17 @@ +package optional + +// NewOptionalUint32 returns an optional Uint32 structure. +func NewOptionalUint32(value uint32) *Uint32 { + return &Uint32{Value: value, IsEmpty: false} +} + +func NewEmptyUint32() *Uint32 { + return &Uint32{IsEmpty: true} +} + +// Uint32 is a simple structure for Uint32 values that can +// optionally be nil. +type Uint32 struct { + Value uint32 + IsEmpty bool +} |