6
6
package org .whispersystems .libsignal .fingerprint ;
7
7
8
8
import org .whispersystems .libsignal .IdentityKey ;
9
+ import org .whispersystems .libsignal .devices .DeviceConsistencySignature ;
10
+ import org .whispersystems .libsignal .util .ByteArrayComparator ;
9
11
import org .whispersystems .libsignal .util .ByteUtil ;
12
+ import org .whispersystems .libsignal .util .IdentityKeyComparator ;
10
13
14
+ import java .io .ByteArrayOutputStream ;
11
15
import java .security .MessageDigest ;
12
16
import java .security .NoSuchAlgorithmException ;
17
+ import java .util .ArrayList ;
18
+ import java .util .Collections ;
19
+ import java .util .Comparator ;
20
+ import java .util .List ;
13
21
14
22
public class NumericFingerprintGenerator implements FingerprintGenerator {
15
23
16
- private static final int VERSION = 0 ;
17
-
18
- private final long iterations ;
24
+ private final int iterations ;
19
25
20
26
/**
21
27
* Construct a fingerprint generator for 60 digit numerics.
@@ -30,7 +36,7 @@ public class NumericFingerprintGenerator implements FingerprintGenerator {
30
36
* - 1400 > 110 bits
31
37
* - 5200 > 112 bits
32
38
*/
33
- public NumericFingerprintGenerator (long iterations ) {
39
+ public NumericFingerprintGenerator (int iterations ) {
34
40
this .iterations = iterations ;
35
41
}
36
42
@@ -47,42 +53,45 @@ public NumericFingerprintGenerator(long iterations) {
47
53
public Fingerprint createFor (String localStableIdentifier , IdentityKey localIdentityKey ,
48
54
String remoteStableIdentifier , IdentityKey remoteIdentityKey )
49
55
{
50
- DisplayableFingerprint displayableFingerprint = new DisplayableFingerprint (getDisplayStringFor (localStableIdentifier , localIdentityKey ),
51
- getDisplayStringFor (remoteStableIdentifier , remoteIdentityKey ));
56
+ DisplayableFingerprint displayableFingerprint = new DisplayableFingerprint (iterations ,
57
+ localStableIdentifier ,
58
+ localIdentityKey ,
59
+ remoteStableIdentifier ,
60
+ remoteIdentityKey );
52
61
53
- ScannableFingerprint scannableFingerprint = new ScannableFingerprint (VERSION ,
54
- localStableIdentifier , localIdentityKey ,
62
+ ScannableFingerprint scannableFingerprint = new ScannableFingerprint (localStableIdentifier , localIdentityKey ,
55
63
remoteStableIdentifier , remoteIdentityKey );
56
64
57
65
return new Fingerprint (displayableFingerprint , scannableFingerprint );
58
66
}
59
67
60
- private String getDisplayStringFor (String stableIdentifier , IdentityKey identityKey ) {
61
- try {
62
- MessageDigest digest = MessageDigest .getInstance ("SHA-512" );
63
- byte [] publicKey = identityKey .getPublicKey ().serialize ();
64
- byte [] hash = ByteUtil .combine (ByteUtil .shortToByteArray (VERSION ),
65
- publicKey , stableIdentifier .getBytes ());
68
+ /**
69
+ * Generate a scannable and displayble fingerprint for logical identities that have multiple
70
+ * physical keys.
71
+ *
72
+ * Do not trust the output of this unless you've been through the device consistency process
73
+ * for the provided localIdentityKeys.
74
+ *
75
+ * @param localStableIdentifier The client's "stable" identifier.
76
+ * @param localIdentityKeys The client's collection of physical identity keys.
77
+ * @param remoteStableIdentifier The remote party's "stable" identifier.
78
+ * @param remoteIdentityKeys The remote party's collection of physical identity key.
79
+ * @return A unique fingerprint for this conversation.
80
+ */
81
+ public Fingerprint createFor (String localStableIdentifier , List <IdentityKey > localIdentityKeys ,
82
+ String remoteStableIdentifier , List <IdentityKey > remoteIdentityKeys )
83
+ {
84
+ DisplayableFingerprint displayableFingerprint = new DisplayableFingerprint (iterations ,
85
+ localStableIdentifier ,
86
+ localIdentityKeys ,
87
+ remoteStableIdentifier ,
88
+ remoteIdentityKeys );
66
89
67
- for (int i =0 ;i <iterations ;i ++) {
68
- digest .update (hash );
69
- hash = digest .digest (publicKey );
70
- }
90
+ ScannableFingerprint scannableFingerprint = new ScannableFingerprint (localStableIdentifier , localIdentityKeys ,
91
+ remoteStableIdentifier , remoteIdentityKeys );
71
92
72
- return getEncodedChunk (hash , 0 ) +
73
- getEncodedChunk (hash , 5 ) +
74
- getEncodedChunk (hash , 10 ) +
75
- getEncodedChunk (hash , 15 ) +
76
- getEncodedChunk (hash , 20 ) +
77
- getEncodedChunk (hash , 25 );
78
- } catch (NoSuchAlgorithmException e ) {
79
- throw new AssertionError (e );
80
- }
93
+ return new Fingerprint (displayableFingerprint , scannableFingerprint );
81
94
}
82
95
83
- private String getEncodedChunk (byte [] hash , int offset ) {
84
- long chunk = ByteUtil .byteArray5ToLong (hash , offset ) % 100000 ;
85
- return String .format ("%05d" , chunk );
86
- }
87
96
88
97
}
0 commit comments