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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
|
package record
import (
"go.mau.fi/libsignal/ecc"
"go.mau.fi/libsignal/util/bytehelper"
)
// SignedPreKeySerializer is an interface for serializing and deserializing
// SignedPreKey objects into bytes. An implementation of this interface should be
// used to encode/decode the object into JSON, Protobuffers, etc.
type SignedPreKeySerializer interface {
Serialize(signedPreKey *SignedPreKeyStructure) []byte
Deserialize(serialized []byte) (*SignedPreKeyStructure, error)
}
// NewSignedPreKeyFromBytes will return a signed prekey record from the given
// bytes using the given serializer.
func NewSignedPreKeyFromBytes(serialized []byte, serializer SignedPreKeySerializer) (*SignedPreKey, error) {
// Use the given serializer to decode the signal message.
signedPreKeyStructure, err := serializer.Deserialize(serialized)
if err != nil {
return nil, err
}
return NewSignedPreKeyFromStruct(signedPreKeyStructure, serializer)
}
// NewSignedPreKeyFromStruct returns a SignedPreKey record using the given
// serializable structure.
func NewSignedPreKeyFromStruct(structure *SignedPreKeyStructure,
serializer SignedPreKeySerializer) (*SignedPreKey, error) {
// Create the signed prekey record from the structure.
signedPreKey := &SignedPreKey{
structure: *structure,
serializer: serializer,
signature: bytehelper.SliceToArray64(structure.Signature),
}
// Generate the ECC key from bytes.
publicKey := ecc.NewDjbECPublicKey(bytehelper.SliceToArray(structure.PublicKey))
privateKey := ecc.NewDjbECPrivateKey(bytehelper.SliceToArray(structure.PrivateKey))
keyPair := ecc.NewECKeyPair(publicKey, privateKey)
signedPreKey.keyPair = keyPair
return signedPreKey, nil
}
// NewSignedPreKey record creates a new signed pre key record
// with the given properties.
func NewSignedPreKey(id uint32, timestamp int64, keyPair *ecc.ECKeyPair,
sig [64]byte, serializer SignedPreKeySerializer) *SignedPreKey {
return &SignedPreKey{
structure: SignedPreKeyStructure{
ID: id,
Timestamp: timestamp,
PublicKey: keyPair.PublicKey().Serialize(),
PrivateKey: bytehelper.ArrayToSlice(keyPair.PrivateKey().Serialize()),
Signature: bytehelper.ArrayToSlice64(sig),
},
keyPair: keyPair,
signature: sig,
serializer: serializer,
}
}
// SignedPreKeyStructure is a flat structure of a signed pre key, used
// for serialization and deserialization.
type SignedPreKeyStructure struct {
ID uint32
PublicKey []byte
PrivateKey []byte
Signature []byte
Timestamp int64
}
// SignedPreKey record is a structure for storing a signed
// pre key in a SignedPreKey store.
type SignedPreKey struct {
structure SignedPreKeyStructure
keyPair *ecc.ECKeyPair
signature [64]byte
serializer SignedPreKeySerializer
}
// ID returns the record's id.
func (s *SignedPreKey) ID() uint32 {
return s.structure.ID
}
// Timestamp returns the record's timestamp
func (s *SignedPreKey) Timestamp() int64 {
return s.structure.Timestamp
}
// KeyPair returns the signed pre key record's key pair.
func (s *SignedPreKey) KeyPair() *ecc.ECKeyPair {
return s.keyPair
}
// Signature returns the record's signed prekey signature.
func (s *SignedPreKey) Signature() [64]byte {
return s.signature
}
// Serialize uses the SignedPreKey serializer to return the SignedPreKey
// as serialized bytes.
func (s *SignedPreKey) Serialize() []byte {
structure := s.structure
return s.serializer.Serialize(&structure)
}
|