1 package org
.asamk
.signal
.manager
.util
;
3 import com
.google
.protobuf
.ByteString
;
5 import org
.signal
.libsignal
.protocol
.IdentityKey
;
6 import org
.signal
.libsignal
.protocol
.IdentityKeyPair
;
7 import org
.signal
.libsignal
.protocol
.ecc
.ECPrivateKey
;
8 import org
.signal
.libsignal
.protocol
.ecc
.ECPublicKey
;
9 import org
.slf4j
.Logger
;
10 import org
.slf4j
.LoggerFactory
;
11 import org
.whispersystems
.signalservice
.internal
.push
.SignalServiceProtos
;
13 public class PaymentUtils
{
15 private final static Logger logger
= LoggerFactory
.getLogger(PaymentUtils
.class);
17 private PaymentUtils() {
21 * Signs the supplied address bytes with the {@link IdentityKeyPair}'s private key and returns a proto that includes it, and it's signature.
23 public static SignalServiceProtos
.PaymentAddress
signPaymentsAddress(
24 byte[] publicAddressBytes
, ECPrivateKey privateKey
26 byte[] signature
= privateKey
.calculateSignature(publicAddressBytes
);
28 return SignalServiceProtos
.PaymentAddress
.newBuilder()
29 .setMobileCoinAddress(SignalServiceProtos
.PaymentAddress
.MobileCoinAddress
.newBuilder()
30 .setAddress(ByteString
.copyFrom(publicAddressBytes
))
31 .setSignature(ByteString
.copyFrom(signature
)))
36 * Verifies that the payments address is signed with the supplied {@link IdentityKey}.
38 * Returns the validated bytes if so, otherwise returns null.
40 public static byte[] verifyPaymentsAddress(
41 SignalServiceProtos
.PaymentAddress paymentAddress
, ECPublicKey publicKey
43 if (!paymentAddress
.hasMobileCoinAddress()) {
44 logger
.debug("Got payment address without mobile coin address, ignoring.");
48 byte[] bytes
= paymentAddress
.getMobileCoinAddress().getAddress().toByteArray();
49 byte[] signature
= paymentAddress
.getMobileCoinAddress().getSignature().toByteArray();
51 if (signature
.length
!= 64 || !publicKey
.verifySignature(bytes
, signature
)) {
52 logger
.debug("Got mobile coin address with invalid signature, ignoring.");