1 package org
.asamk
.signal
.manager
.util
;
3 import org
.signal
.libsignal
.protocol
.IdentityKey
;
4 import org
.signal
.libsignal
.protocol
.IdentityKeyPair
;
5 import org
.signal
.libsignal
.protocol
.ecc
.ECPrivateKey
;
6 import org
.signal
.libsignal
.protocol
.ecc
.ECPublicKey
;
7 import org
.slf4j
.Logger
;
8 import org
.slf4j
.LoggerFactory
;
9 import org
.whispersystems
.signalservice
.internal
.push
.PaymentAddress
;
11 import okio
.ByteString
;
13 public class PaymentUtils
{
15 private static final 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 PaymentAddress
signPaymentsAddress(
24 byte[] publicAddressBytes
, ECPrivateKey privateKey
26 byte[] signature
= privateKey
.calculateSignature(publicAddressBytes
);
28 return new PaymentAddress
.Builder().mobileCoinAddress(new PaymentAddress
.MobileCoinAddress
.Builder().address(
29 ByteString
.of(publicAddressBytes
)).signature(ByteString
.of(signature
)).build()).build();
33 * Verifies that the payments address is signed with the supplied {@link IdentityKey}.
35 * Returns the validated bytes if so, otherwise returns null.
37 public static byte[] verifyPaymentsAddress(
38 PaymentAddress paymentAddress
, ECPublicKey publicKey
40 final var mobileCoinAddress
= paymentAddress
.mobileCoinAddress
;
41 if (mobileCoinAddress
== null || mobileCoinAddress
.address
== null || mobileCoinAddress
.signature
== null) {
42 logger
.debug("Got payment address without mobile coin address, ignoring.");
46 byte[] bytes
= mobileCoinAddress
.address
.toByteArray();
47 byte[] signature
= mobileCoinAddress
.signature
.toByteArray();
49 if (signature
.length
!= 64 || !publicKey
.verifySignature(bytes
, signature
)) {
50 logger
.debug("Got mobile coin address with invalid signature, ignoring.");