1 package org
.asamk
.signal
.manager
.util
;
3 import org
.signal
.zkgroup
.InvalidInputException
;
4 import org
.signal
.zkgroup
.profiles
.ProfileKey
;
5 import org
.whispersystems
.libsignal
.IdentityKey
;
6 import org
.whispersystems
.libsignal
.IdentityKeyPair
;
7 import org
.whispersystems
.libsignal
.InvalidKeyException
;
8 import org
.whispersystems
.libsignal
.ecc
.Curve
;
9 import org
.whispersystems
.libsignal
.ecc
.ECKeyPair
;
10 import org
.whispersystems
.libsignal
.ecc
.ECPrivateKey
;
11 import org
.whispersystems
.libsignal
.state
.PreKeyRecord
;
12 import org
.whispersystems
.libsignal
.state
.SignedPreKeyRecord
;
13 import org
.whispersystems
.libsignal
.util
.Medium
;
14 import org
.whispersystems
.signalservice
.api
.kbs
.MasterKey
;
16 import java
.security
.SecureRandom
;
17 import java
.util
.ArrayList
;
18 import java
.util
.Base64
;
19 import java
.util
.List
;
21 public class KeyUtils
{
23 private static final SecureRandom secureRandom
= new SecureRandom();
28 public static IdentityKeyPair
generateIdentityKeyPair() {
29 ECKeyPair djbKeyPair
= Curve
.generateKeyPair();
30 IdentityKey djbIdentityKey
= new IdentityKey(djbKeyPair
.getPublicKey());
31 ECPrivateKey djbPrivateKey
= djbKeyPair
.getPrivateKey();
33 return new IdentityKeyPair(djbIdentityKey
, djbPrivateKey
);
36 public static List
<PreKeyRecord
> generatePreKeyRecords(final int offset
, final int batchSize
) {
37 List
<PreKeyRecord
> records
= new ArrayList
<>(batchSize
);
38 for (int i
= 0; i
< batchSize
; i
++) {
39 int preKeyId
= (offset
+ i
) % Medium
.MAX_VALUE
;
40 ECKeyPair keyPair
= Curve
.generateKeyPair();
41 PreKeyRecord
record = new PreKeyRecord(preKeyId
, keyPair
);
48 public static SignedPreKeyRecord
generateSignedPreKeyRecord(
49 final IdentityKeyPair identityKeyPair
, final int signedPreKeyId
51 ECKeyPair keyPair
= Curve
.generateKeyPair();
54 signature
= Curve
.calculateSignature(identityKeyPair
.getPrivateKey(), keyPair
.getPublicKey().serialize());
55 } catch (InvalidKeyException e
) {
56 throw new AssertionError(e
);
58 return new SignedPreKeyRecord(signedPreKeyId
, System
.currentTimeMillis(), keyPair
, signature
);
61 public static String
createSignalingKey() {
65 public static ProfileKey
createProfileKey() {
67 return new ProfileKey(getSecretBytes(32));
68 } catch (InvalidInputException e
) {
69 throw new AssertionError("Profile key is guaranteed to be 32 bytes here");
73 public static String
createPassword() {
77 public static byte[] createStickerUploadKey() {
78 return getSecretBytes(32);
81 public static MasterKey
createMasterKey() {
82 return MasterKey
.createNew(secureRandom
);
85 private static String
getSecret(int size
) {
86 byte[] secret
= getSecretBytes(size
);
87 return Base64
.getEncoder().encodeToString(secret
);
90 public static byte[] getSecretBytes(int size
) {
91 byte[] secret
= new byte[size
];
92 secureRandom
.nextBytes(secret
);