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
.ECPrivateKey
;
10 import org
.whispersystems
.libsignal
.state
.PreKeyRecord
;
11 import org
.whispersystems
.libsignal
.state
.SignedPreKeyRecord
;
12 import org
.whispersystems
.libsignal
.util
.Medium
;
13 import org
.whispersystems
.signalservice
.api
.kbs
.MasterKey
;
15 import java
.security
.SecureRandom
;
16 import java
.util
.ArrayList
;
17 import java
.util
.Base64
;
18 import java
.util
.List
;
20 public class KeyUtils
{
22 private static final SecureRandom secureRandom
= new SecureRandom();
27 public static IdentityKeyPair
getIdentityKeyPair(byte[] publicKeyBytes
, byte[] privateKeyBytes
) {
29 IdentityKey publicKey
= new IdentityKey(publicKeyBytes
);
30 ECPrivateKey privateKey
= Curve
.decodePrivatePoint(privateKeyBytes
);
32 return new IdentityKeyPair(publicKey
, privateKey
);
33 } catch (InvalidKeyException e
) {
34 throw new AssertionError(e
);
38 public static IdentityKeyPair
generateIdentityKeyPair() {
39 var djbKeyPair
= Curve
.generateKeyPair();
40 var djbIdentityKey
= new IdentityKey(djbKeyPair
.getPublicKey());
41 var djbPrivateKey
= djbKeyPair
.getPrivateKey();
43 return new IdentityKeyPair(djbIdentityKey
, djbPrivateKey
);
46 public static List
<PreKeyRecord
> generatePreKeyRecords(final int offset
, final int batchSize
) {
47 var records
= new ArrayList
<PreKeyRecord
>(batchSize
);
48 for (var i
= 0; i
< batchSize
; i
++) {
49 var preKeyId
= (offset
+ i
) % Medium
.MAX_VALUE
;
50 var keyPair
= Curve
.generateKeyPair();
51 var record = new PreKeyRecord(preKeyId
, keyPair
);
58 public static SignedPreKeyRecord
generateSignedPreKeyRecord(
59 final IdentityKeyPair identityKeyPair
, final int signedPreKeyId
61 var keyPair
= Curve
.generateKeyPair();
64 signature
= Curve
.calculateSignature(identityKeyPair
.getPrivateKey(), keyPair
.getPublicKey().serialize());
65 } catch (InvalidKeyException e
) {
66 throw new AssertionError(e
);
68 return new SignedPreKeyRecord(signedPreKeyId
, System
.currentTimeMillis(), keyPair
, signature
);
71 public static ProfileKey
createProfileKey() {
73 return new ProfileKey(getSecretBytes(32));
74 } catch (InvalidInputException e
) {
75 throw new AssertionError("Profile key is guaranteed to be 32 bytes here");
79 public static String
createPassword() {
83 public static byte[] createStickerUploadKey() {
84 return getSecretBytes(32);
87 public static MasterKey
createMasterKey() {
88 return MasterKey
.createNew(secureRandom
);
91 private static String
getSecret(int size
) {
92 var secret
= getSecretBytes(size
);
93 return Base64
.getEncoder().encodeToString(secret
);
96 public static byte[] getSecretBytes(int size
) {
97 var secret
= new byte[size
];
98 secureRandom
.nextBytes(secret
);