summaryrefslogtreecommitdiffstats
path: root/vendor/go.mau.fi/libsignal/util/keyhelper/KeyHelper.go
blob: 62481cc19520f1a29c22b219e40a2b4bf45bd9b8 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
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 --------------