Updated and fixed JavaDoc
This commit is contained in:
		@@ -44,7 +44,7 @@ import static ch.dissem.bitmessage.utils.UnixTime.DAY;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Use this class if you want to create a Bitmessage client.
 | 
					 * Use this class if you want to create a Bitmessage client.
 | 
				
			||||||
 * <p/>
 | 
					 * <p>
 | 
				
			||||||
 * You'll need the Builder to create a BitmessageContext, and set the following properties:
 | 
					 * You'll need the Builder to create a BitmessageContext, and set the following properties:
 | 
				
			||||||
 * <ul>
 | 
					 * <ul>
 | 
				
			||||||
 * <li>addressRepo</li>
 | 
					 * <li>addressRepo</li>
 | 
				
			||||||
@@ -55,8 +55,10 @@ import static ch.dissem.bitmessage.utils.UnixTime.DAY;
 | 
				
			|||||||
 * <li>streams</li>
 | 
					 * <li>streams</li>
 | 
				
			||||||
 * </ul>
 | 
					 * </ul>
 | 
				
			||||||
 * The default implementations in the different module builds can be used.
 | 
					 * The default implementations in the different module builds can be used.
 | 
				
			||||||
 * <p/>
 | 
					 * </p>
 | 
				
			||||||
 | 
					 * <p>
 | 
				
			||||||
 * The port defaults to 8444 (the default Bitmessage port)
 | 
					 * The port defaults to 8444 (the default Bitmessage port)
 | 
				
			||||||
 | 
					 * </p>
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
public class BitmessageContext {
 | 
					public class BitmessageContext {
 | 
				
			||||||
    public static final int CURRENT_VERSION = 3;
 | 
					    public static final int CURRENT_VERSION = 3;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -35,8 +35,9 @@ import static ch.dissem.bitmessage.utils.UnixTime.DAY;
 | 
				
			|||||||
 * The internal context should normally only be used for port implementations. If you need it in your client
 | 
					 * The internal context should normally only be used for port implementations. If you need it in your client
 | 
				
			||||||
 * implementation, you're either doing something wrong, something very weird, or the BitmessageContext should
 | 
					 * implementation, you're either doing something wrong, something very weird, or the BitmessageContext should
 | 
				
			||||||
 * get extended.
 | 
					 * get extended.
 | 
				
			||||||
 * <p/>
 | 
					 * <p>
 | 
				
			||||||
 * On the other hand, if you need the BitmessageContext in a port implementation, the same thing might apply.
 | 
					 * On the other hand, if you need the BitmessageContext in a port implementation, the same thing might apply.
 | 
				
			||||||
 | 
					 * </p>
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
public class InternalContext {
 | 
					public class InternalContext {
 | 
				
			||||||
    private final static Logger LOG = LoggerFactory.getLogger(InternalContext.class);
 | 
					    private final static Logger LOG = LoggerFactory.getLogger(InternalContext.class);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -158,7 +158,7 @@ public class BitmessageAddress {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Returns the private key used to decrypt Pubkey objects (for v4 addresses) and broadcasts.
 | 
					     * @return the private key used to decrypt Pubkey objects (for v4 addresses) and broadcasts.
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public byte[] getPublicDecryptionKey() {
 | 
					    public byte[] getPublicDecryptionKey() {
 | 
				
			||||||
        return publicDecryptionKey;
 | 
					        return publicDecryptionKey;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -47,11 +47,11 @@ public class CryptoBox implements Streamable {
 | 
				
			|||||||
    private final byte[] mac;
 | 
					    private final byte[] mac;
 | 
				
			||||||
    private byte[] encrypted;
 | 
					    private byte[] encrypted;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public CryptoBox(Streamable data, byte[] encryptionKey) {
 | 
					    public CryptoBox(Streamable data, byte[] encryptionKey) throws IOException {
 | 
				
			||||||
        this(data, Security.keyToPoint(encryptionKey));
 | 
					        this(data, Security.keyToPoint(encryptionKey));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public CryptoBox(Streamable data, ECPoint K) {
 | 
					    public CryptoBox(Streamable data, ECPoint K) throws IOException {
 | 
				
			||||||
        curveType = 0x02CA;
 | 
					        curveType = 0x02CA;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // 1. The destination public key is called K.
 | 
					        // 1. The destination public key is called K.
 | 
				
			||||||
@@ -71,7 +71,7 @@ public class CryptoBox implements Streamable {
 | 
				
			|||||||
        byte[] key_m = Arrays.copyOfRange(H, 32, 64);
 | 
					        byte[] key_m = Arrays.copyOfRange(H, 32, 64);
 | 
				
			||||||
        // 7. Pad the input text to a multiple of 16 bytes, in accordance to PKCS7.
 | 
					        // 7. Pad the input text to a multiple of 16 bytes, in accordance to PKCS7.
 | 
				
			||||||
        // 8. Encrypt the data with AES-256-CBC, using IV as initialization vector, key_e as encryption key and the padded input text as payload. Call the output cipher text.
 | 
					        // 8. Encrypt the data with AES-256-CBC, using IV as initialization vector, key_e as encryption key and the padded input text as payload. Call the output cipher text.
 | 
				
			||||||
        encrypted = crypt(true, Bytes.from(data), key_e);
 | 
					        encrypted = crypt(true, Encode.bytes(data), key_e);
 | 
				
			||||||
        // 9. Calculate a 32 byte MAC with HMACSHA256, using key_m as salt and IV + R + cipher text as data. Call the output MAC.
 | 
					        // 9. Calculate a 32 byte MAC with HMACSHA256, using key_m as salt and IV + R + cipher text as data. Call the output MAC.
 | 
				
			||||||
        mac = calculateMac(key_m);
 | 
					        mac = calculateMac(key_m);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -99,6 +99,9 @@ public class CryptoBox implements Streamable {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
 | 
					     * @param privateKey a private key, typically should be 32 bytes long
 | 
				
			||||||
 | 
					     * @return an InputStream yielding the decrypted data
 | 
				
			||||||
 | 
					     * @throws DecryptionFailedException if the payload can't be decrypted using this private key
 | 
				
			||||||
     * @see <a href='https://bitmessage.org/wiki/Encryption#Decryption'>https://bitmessage.org/wiki/Encryption#Decryption</a>
 | 
					     * @see <a href='https://bitmessage.org/wiki/Encryption#Decryption'>https://bitmessage.org/wiki/Encryption#Decryption</a>
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public InputStream decrypt(byte[] privateKey) throws DecryptionFailedException {
 | 
					    public InputStream decrypt(byte[] privateKey) throws DecryptionFailedException {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -50,7 +50,7 @@ public class GetPubkey extends ObjectPayload {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Returns an array of bytes that represent either the ripe, or the tag of an address, depending on the
 | 
					     * @return an array of bytes that represent either the ripe, or the tag of an address, depending on the
 | 
				
			||||||
     * address version.
 | 
					     * address version.
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public byte[] getRipeTag() {
 | 
					    public byte[] getRipeTag() {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -50,7 +50,7 @@ public abstract class ObjectPayload implements Streamable {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * The ECDSA signature which, as of protocol v3, covers the object header starting with the time,
 | 
					     * @return the ECDSA signature which, as of protocol v3, covers the object header starting with the time,
 | 
				
			||||||
     * appended with the data described in this table down to the extra_bytes. Therefore, this must
 | 
					     * appended with the data described in this table down to the extra_bytes. Therefore, this must
 | 
				
			||||||
     * be checked and set in the {@link ObjectMessage} object.
 | 
					     * be checked and set in the {@link ObjectMessage} object.
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -31,12 +31,15 @@ public class Label {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * RGBA representation for the color.
 | 
					     * @return RGBA representation for the color.
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public int getColor() {
 | 
					    public int getColor() {
 | 
				
			||||||
        return color;
 | 
					        return color;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @param color RGBA representation for the color.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    public void setColor(int color) {
 | 
					    public void setColor(int color) {
 | 
				
			||||||
        this.color = color;
 | 
					        this.color = color;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -50,14 +53,14 @@ public class Label {
 | 
				
			|||||||
        return id;
 | 
					        return id;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public Type getType() {
 | 
					 | 
				
			||||||
        return type;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public void setId(Object id) {
 | 
					    public void setId(Object id) {
 | 
				
			||||||
        this.id = id;
 | 
					        this.id = id;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public Type getType() {
 | 
				
			||||||
 | 
					        return type;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    public boolean equals(Object o) {
 | 
					    public boolean equals(Object o) {
 | 
				
			||||||
        if (this == o) return true;
 | 
					        if (this == o) return true;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -26,7 +26,7 @@ public interface AddressRepository {
 | 
				
			|||||||
    BitmessageAddress findIdentity(byte[] ripeOrTag);
 | 
					    BitmessageAddress findIdentity(byte[] ripeOrTag);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Returns all Bitmessage addresses that belong to this user, i.e. have a private key.
 | 
					     * @return all Bitmessage addresses that belong to this user, i.e. have a private key.
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    List<BitmessageAddress> getIdentities();
 | 
					    List<BitmessageAddress> getIdentities();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -35,7 +35,7 @@ public interface AddressRepository {
 | 
				
			|||||||
    List<BitmessageAddress> getSubscriptions(long broadcastVersion);
 | 
					    List<BitmessageAddress> getSubscriptions(long broadcastVersion);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Returns all Bitmessage addresses that have no private key.
 | 
					     * @return all Bitmessage addresses that have no private key.
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    List<BitmessageAddress> getContacts();
 | 
					    List<BitmessageAddress> getContacts();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -29,9 +29,8 @@ import static java.util.Arrays.copyOfRange;
 | 
				
			|||||||
 * @author Christian Basler: I removed some dependencies to the BitcoinJ code so it can be used here more easily.
 | 
					 * @author Christian Basler: I removed some dependencies to the BitcoinJ code so it can be used here more easily.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
public class Base58 {
 | 
					public class Base58 {
 | 
				
			||||||
    private static char[] ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz".toCharArray();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    private static final int[] INDEXES = new int[128];
 | 
					    private static final int[] INDEXES = new int[128];
 | 
				
			||||||
 | 
					    private static char[] ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz".toCharArray();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    static {
 | 
					    static {
 | 
				
			||||||
        for (int i = 0; i < INDEXES.length; i++) {
 | 
					        for (int i = 0; i < INDEXES.length; i++) {
 | 
				
			||||||
@@ -44,6 +43,9 @@ public class Base58 {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Encodes the given bytes in base58. No checksum is appended.
 | 
					     * Encodes the given bytes in base58. No checksum is appended.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param input to encode
 | 
				
			||||||
 | 
					     * @return base58 encoded input
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public static String encode(byte[] input) {
 | 
					    public static String encode(byte[] input) {
 | 
				
			||||||
        if (input.length == 0) {
 | 
					        if (input.length == 0) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -38,6 +38,9 @@ public class Bytes {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Increases nonce by value, which is used as an unsigned byte value.
 | 
					     * Increases nonce by value, which is used as an unsigned byte value.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param nonce an unsigned number
 | 
				
			||||||
 | 
					     * @param value to be added to nonce
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public static void inc(byte[] nonce, byte value) {
 | 
					    public static void inc(byte[] nonce, byte value) {
 | 
				
			||||||
        int i = nonce.length - 1;
 | 
					        int i = nonce.length - 1;
 | 
				
			||||||
@@ -54,7 +57,7 @@ public class Bytes {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Returns true if a < b.
 | 
					     * @return true if a < b.
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public static boolean lt(byte[] a, byte[] b) {
 | 
					    public static boolean lt(byte[] a, byte[] b) {
 | 
				
			||||||
        byte[] max = (a.length > b.length ? a : b);
 | 
					        byte[] max = (a.length > b.length ? a : b);
 | 
				
			||||||
@@ -73,7 +76,7 @@ public class Bytes {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Returns true if a < b, where the first [size] bytes are used as the numbers to check.
 | 
					     * @return true if a < b, where the first [size] bytes are used as the numbers to check.
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public static boolean lt(byte[] a, byte[] b, int size) {
 | 
					    public static boolean lt(byte[] a, byte[] b, int size) {
 | 
				
			||||||
        for (int i = 0; i < size; i++) {
 | 
					        for (int i = 0; i < size; i++) {
 | 
				
			||||||
@@ -91,7 +94,7 @@ public class Bytes {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Returns a new byte array of length, left-padded with '0'.
 | 
					     * @return a new byte array of length, left-padded with '0'.
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public static byte[] expand(byte[] source, int size) {
 | 
					    public static byte[] expand(byte[] source, int size) {
 | 
				
			||||||
        byte[] result = new byte[size];
 | 
					        byte[] result = new byte[size];
 | 
				
			||||||
@@ -100,7 +103,7 @@ public class Bytes {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Returns a new byte array containing the first <em>size</em> bytes of the given array.
 | 
					     * @return a new byte array containing the first <em>size</em> bytes of the given array.
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public static byte[] truncate(byte[] source, int size) {
 | 
					    public static byte[] truncate(byte[] source, int size) {
 | 
				
			||||||
        byte[] result = new byte[size];
 | 
					        byte[] result = new byte[size];
 | 
				
			||||||
@@ -109,7 +112,7 @@ public class Bytes {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Returns the byte array that hex represents. This is meant for test use and should be rewritten if used in
 | 
					     * @return the byte array that hex represents. This is meant for test use and should be rewritten if used in
 | 
				
			||||||
     * production code.
 | 
					     * production code.
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public static byte[] fromHex(String hex) {
 | 
					    public static byte[] fromHex(String hex) {
 | 
				
			||||||
@@ -136,7 +139,7 @@ public class Bytes {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Returns the number of leading '0' of a byte array.
 | 
					     * @return the number of leading '0' of a byte array.
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public static int numberOfLeadingZeros(byte[] bytes) {
 | 
					    public static int numberOfLeadingZeros(byte[] bytes) {
 | 
				
			||||||
        int i;
 | 
					        int i;
 | 
				
			||||||
@@ -145,24 +148,4 @@ public class Bytes {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
        return i;
 | 
					        return i;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * Returns a copy of bytes with leading zeroes stripped.
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    public static byte[] stripLeadingZeros(byte[] bytes) {
 | 
					 | 
				
			||||||
        return Arrays.copyOfRange(bytes, numberOfLeadingZeros(bytes), bytes.length);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * Returns the byte array of the serialized data.
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    public static byte[] from(Streamable data) {
 | 
					 | 
				
			||||||
        try {
 | 
					 | 
				
			||||||
            ByteArrayOutputStream out = new ByteArrayOutputStream();
 | 
					 | 
				
			||||||
            data.write(out);
 | 
					 | 
				
			||||||
            return out.toByteArray();
 | 
					 | 
				
			||||||
        } catch (IOException e) {
 | 
					 | 
				
			||||||
            throw new RuntimeException(e);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -25,8 +25,11 @@ public class Collections {
 | 
				
			|||||||
    private final static Random RANDOM = new Random();
 | 
					    private final static Random RANDOM = new Random();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Returns a random subset of the given collection, or a copy of the collection if it's not larger than count.
 | 
					     * @param count      the number of elements to return (if possible)
 | 
				
			||||||
     * The randomness
 | 
					     * @param collection the collection to take samples from
 | 
				
			||||||
 | 
					     * @return a random subset of the given collection, or a copy of the collection if it's not larger than count. The
 | 
				
			||||||
 | 
					     * result is by no means securely random, but should be random enough so not the same objects get selected over
 | 
				
			||||||
 | 
					     * and over again.
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public static <T> List<T> selectRandom(int count, Collection<T> collection) {
 | 
					    public static <T> List<T> selectRandom(int count, Collection<T> collection) {
 | 
				
			||||||
        ArrayList<T> result = new ArrayList<>(count);
 | 
					        ArrayList<T> result = new ArrayList<>(count);
 | 
				
			||||||
@@ -44,7 +47,7 @@ public class Collections {
 | 
				
			|||||||
                } else {
 | 
					                } else {
 | 
				
			||||||
                    result.add(item);
 | 
					                    result.add(item);
 | 
				
			||||||
                    resultRest--;
 | 
					                    resultRest--;
 | 
				
			||||||
                    if (resultRest == 0){
 | 
					                    if (resultRest == 0) {
 | 
				
			||||||
                        break;
 | 
					                        break;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    skipMax = (int) Math.ceil(collectionRest / resultRest);
 | 
					                    skipMax = (int) Math.ceil(collectionRest / resultRest);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -112,7 +112,9 @@ public class Encode {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Returns an array of bytes representing the given streamable object.
 | 
					     * @param streamable the object to be serialized
 | 
				
			||||||
 | 
					     * @return an array of bytes representing the given streamable object.
 | 
				
			||||||
 | 
					     * @throws IOException if an I/O error occurs.
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public static byte[] bytes(Streamable streamable) throws IOException {
 | 
					    public static byte[] bytes(Streamable streamable) throws IOException {
 | 
				
			||||||
        ByteArrayOutputStream stream = new ByteArrayOutputStream();
 | 
					        ByteArrayOutputStream stream = new ByteArrayOutputStream();
 | 
				
			||||||
@@ -121,8 +123,10 @@ public class Encode {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Returns the bytes of the given streamable object, 0-padded such that the final
 | 
					     * @param streamable the object to be serialized
 | 
				
			||||||
     * length is x*padding.
 | 
					     * @param padding    the result will be padded such that its length is a multiple of <em>padding</em>
 | 
				
			||||||
 | 
					     * @return the bytes of the given {@link Streamable} object, 0-padded such that the final length is x*padding.
 | 
				
			||||||
 | 
					     * @throws IOException if an I/O error occurs.
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public static byte[] bytes(Streamable streamable, int padding) throws IOException {
 | 
					    public static byte[] bytes(Streamable streamable, int padding) throws IOException {
 | 
				
			||||||
        ByteArrayOutputStream stream = new ByteArrayOutputStream();
 | 
					        ByteArrayOutputStream stream = new ByteArrayOutputStream();
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -40,7 +40,8 @@ import java.security.spec.KeySpec;
 | 
				
			|||||||
import java.util.Arrays;
 | 
					import java.util.Arrays;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Provides some methods to help with hashing and encryption.
 | 
					 * Provides some methods to help with hashing and encryption. All randoms are created using {@link SecureRandom},
 | 
				
			||||||
 | 
					 * which should be secure enough.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
public class Security {
 | 
					public class Security {
 | 
				
			||||||
    public static final Logger LOG = LoggerFactory.getLogger(Security.class);
 | 
					    public static final Logger LOG = LoggerFactory.getLogger(Security.class);
 | 
				
			||||||
@@ -52,10 +53,26 @@ public class Security {
 | 
				
			|||||||
        java.security.Security.addProvider(new BouncyCastleProvider());
 | 
					        java.security.Security.addProvider(new BouncyCastleProvider());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * A helper method to calculate SHA-512 hashes. Please note that a new {@link MessageDigest} object is created at
 | 
				
			||||||
 | 
					     * each call (to ensure thread safety), so you shouldn't use this if you need to do many hash calculations in
 | 
				
			||||||
 | 
					     * success on the same thread.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param data to get hashed
 | 
				
			||||||
 | 
					     * @return SHA-512 hash of data
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    public static byte[] sha512(byte[]... data) {
 | 
					    public static byte[] sha512(byte[]... data) {
 | 
				
			||||||
        return hash("SHA-512", data);
 | 
					        return hash("SHA-512", data);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * A helper method to calculate doubleSHA-512 hashes. Please note that a new {@link MessageDigest} object is created
 | 
				
			||||||
 | 
					     * at each call (to ensure thread safety), so you shouldn't use this if you need to do many hash calculations in
 | 
				
			||||||
 | 
					     * success on the same thread.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param data to get hashed
 | 
				
			||||||
 | 
					     * @return SHA-512 hash of data
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    public static byte[] doubleSha512(byte[]... data) {
 | 
					    public static byte[] doubleSha512(byte[]... data) {
 | 
				
			||||||
        MessageDigest mda = md("SHA-512");
 | 
					        MessageDigest mda = md("SHA-512");
 | 
				
			||||||
        for (byte[] d : data) {
 | 
					        for (byte[] d : data) {
 | 
				
			||||||
@@ -64,33 +81,97 @@ public class Security {
 | 
				
			|||||||
        return mda.digest(mda.digest());
 | 
					        return mda.digest(mda.digest());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * A helper method to calculate double SHA-512 hashes. This method allows to only use a part of the available bytes
 | 
				
			||||||
 | 
					     * to use for the hash calculation.
 | 
				
			||||||
 | 
					     * <p>
 | 
				
			||||||
 | 
					     * Please note that a new {@link MessageDigest} object is created at each call (to ensure thread safety), so you
 | 
				
			||||||
 | 
					     * shouldn't use this if you need to do many hash calculations in short order on the same thread.
 | 
				
			||||||
 | 
					     * </p>
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param data   to get hashed
 | 
				
			||||||
 | 
					     * @param length number of bytes to be taken into account
 | 
				
			||||||
 | 
					     * @return SHA-512 hash of data
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    public static byte[] doubleSha512(byte[] data, int length) {
 | 
					    public static byte[] doubleSha512(byte[] data, int length) {
 | 
				
			||||||
        MessageDigest mda = md("SHA-512");
 | 
					        MessageDigest mda = md("SHA-512");
 | 
				
			||||||
        mda.update(data, 0, length);
 | 
					        mda.update(data, 0, length);
 | 
				
			||||||
        return mda.digest(mda.digest());
 | 
					        return mda.digest(mda.digest());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * A helper method to calculate RIPEMD-160 hashes. Supplying multiple byte arrays has the same result as a
 | 
				
			||||||
 | 
					     * concatenation of all arrays, but might perform better.
 | 
				
			||||||
 | 
					     * <p>
 | 
				
			||||||
 | 
					     * Please note that a new {@link MessageDigest} object is created at
 | 
				
			||||||
 | 
					     * each call (to ensure thread safety), so you shouldn't use this if you need to do many hash calculations in short
 | 
				
			||||||
 | 
					     * order on the same thread.
 | 
				
			||||||
 | 
					     * </p>
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param data to get hashed
 | 
				
			||||||
 | 
					     * @return RIPEMD-160 hash of data
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    public static byte[] ripemd160(byte[]... data) {
 | 
					    public static byte[] ripemd160(byte[]... data) {
 | 
				
			||||||
        return hash("RIPEMD160", data);
 | 
					        return hash("RIPEMD160", data);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * A helper method to calculate double SHA-256 hashes. This method allows to only use a part of the available bytes
 | 
				
			||||||
 | 
					     * to use for the hash calculation.
 | 
				
			||||||
 | 
					     * <p>
 | 
				
			||||||
 | 
					     * Please note that a new {@link MessageDigest} object is created at
 | 
				
			||||||
 | 
					     * each call (to ensure thread safety), so you shouldn't use this if you need to do many hash calculations in short
 | 
				
			||||||
 | 
					     * order on the same thread.
 | 
				
			||||||
 | 
					     * </p>
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param data   to get hashed
 | 
				
			||||||
 | 
					     * @param length number of bytes to be taken into account
 | 
				
			||||||
 | 
					     * @return SHA-256 hash of data
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    public static byte[] doubleSha256(byte[] data, int length) {
 | 
					    public static byte[] doubleSha256(byte[] data, int length) {
 | 
				
			||||||
        MessageDigest mda = md("SHA-256");
 | 
					        MessageDigest mda = md("SHA-256");
 | 
				
			||||||
        mda.update(data, 0, length);
 | 
					        mda.update(data, 0, length);
 | 
				
			||||||
        return mda.digest(mda.digest());
 | 
					        return mda.digest(mda.digest());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * A helper method to calculate SHA-1 hashes. Supplying multiple byte arrays has the same result as a
 | 
				
			||||||
 | 
					     * concatenation of all arrays, but might perform better.
 | 
				
			||||||
 | 
					     * <p>
 | 
				
			||||||
 | 
					     * Please note that a new {@link MessageDigest} object is created at
 | 
				
			||||||
 | 
					     * each call (to ensure thread safety), so you shouldn't use this if you need to do many hash calculations in short
 | 
				
			||||||
 | 
					     * order on the same thread.
 | 
				
			||||||
 | 
					     * </p>
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param data to get hashed
 | 
				
			||||||
 | 
					     * @return SHA hash of data
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    public static byte[] sha1(byte[]... data) {
 | 
					    public static byte[] sha1(byte[]... data) {
 | 
				
			||||||
        return hash("SHA-1", data);
 | 
					        return hash("SHA-1", data);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @param length number of bytes to return
 | 
				
			||||||
 | 
					     * @return an array of the given size containing random bytes
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    public static byte[] randomBytes(int length) {
 | 
					    public static byte[] randomBytes(int length) {
 | 
				
			||||||
        byte[] result = new byte[length];
 | 
					        byte[] result = new byte[length];
 | 
				
			||||||
        RANDOM.nextBytes(result);
 | 
					        RANDOM.nextBytes(result);
 | 
				
			||||||
        return result;
 | 
					        return result;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static void doProofOfWork(ObjectMessage object, ProofOfWorkEngine worker, long nonceTrialsPerByte, long extraBytes) {
 | 
					    /**
 | 
				
			||||||
 | 
					     * Calculates the proof of work. This might take a long time, depending on the hardware, message size and time to
 | 
				
			||||||
 | 
					     * live.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param object             to do the proof of work for
 | 
				
			||||||
 | 
					     * @param worker             doing the actual proof of work
 | 
				
			||||||
 | 
					     * @param nonceTrialsPerByte difficulty
 | 
				
			||||||
 | 
					     * @param extraBytes         bytes to add to the object size (makes it more difficult to send small messages)
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public static void doProofOfWork(ObjectMessage object, ProofOfWorkEngine worker, long nonceTrialsPerByte,
 | 
				
			||||||
 | 
					                                     long extraBytes) {
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
            if (nonceTrialsPerByte < 1000) nonceTrialsPerByte = 1000;
 | 
					            if (nonceTrialsPerByte < 1000) nonceTrialsPerByte = 1000;
 | 
				
			||||||
            if (extraBytes < 1000) extraBytes = 1000;
 | 
					            if (extraBytes < 1000) extraBytes = 1000;
 | 
				
			||||||
@@ -107,9 +188,13 @@ public class Security {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * @throws InsufficientProofOfWorkException if proof of work doesn't check out
 | 
					     * @param object             to be checked
 | 
				
			||||||
 | 
					     * @param nonceTrialsPerByte difficulty
 | 
				
			||||||
 | 
					     * @param extraBytes         bytes to add to the object size
 | 
				
			||||||
 | 
					     * @throws InsufficientProofOfWorkException if proof of work doesn't check out (makes it more difficult to send small messages)
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public static void checkProofOfWork(ObjectMessage object, long nonceTrialsPerByte, long extraBytes) throws IOException {
 | 
					    public static void checkProofOfWork(ObjectMessage object, long nonceTrialsPerByte, long extraBytes)
 | 
				
			||||||
 | 
					            throws IOException {
 | 
				
			||||||
        byte[] target = getProofOfWorkTarget(object, nonceTrialsPerByte, extraBytes);
 | 
					        byte[] target = getProofOfWorkTarget(object, nonceTrialsPerByte, extraBytes);
 | 
				
			||||||
        byte[] value = Security.doubleSha512(object.getNonce(), getInitialHash(object));
 | 
					        byte[] value = Security.doubleSha512(object.getNonce(), getInitialHash(object));
 | 
				
			||||||
        if (Bytes.lt(target, value, 8)) {
 | 
					        if (Bytes.lt(target, value, 8)) {
 | 
				
			||||||
@@ -146,6 +231,13 @@ public class Security {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Calculates the MAC for a message (data)
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param key_m the symmetric key used
 | 
				
			||||||
 | 
					     * @param data  the message data to calculate the MAC for
 | 
				
			||||||
 | 
					     * @return the MAC
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    public static byte[] mac(byte[] key_m, byte[] data) {
 | 
					    public static byte[] mac(byte[] key_m, byte[] data) {
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
            Mac mac = Mac.getInstance("HmacSHA256", "BC");
 | 
					            Mac mac = Mac.getInstance("HmacSHA256", "BC");
 | 
				
			||||||
@@ -156,6 +248,18 @@ public class Security {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Create a new public key fom given private keys.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param version              of the public key / address
 | 
				
			||||||
 | 
					     * @param stream               of the address
 | 
				
			||||||
 | 
					     * @param privateSigningKey    private key used for signing
 | 
				
			||||||
 | 
					     * @param privateEncryptionKey private key used for encryption
 | 
				
			||||||
 | 
					     * @param nonceTrialsPerByte   proof of work difficulty
 | 
				
			||||||
 | 
					     * @param extraBytes           bytes to add for the proof of work (make it harder for small messages)
 | 
				
			||||||
 | 
					     * @param features             of the address
 | 
				
			||||||
 | 
					     * @return a public key object
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    public static Pubkey createPubkey(long version, long stream, byte[] privateSigningKey, byte[] privateEncryptionKey,
 | 
					    public static Pubkey createPubkey(long version, long stream, byte[] privateSigningKey, byte[] privateEncryptionKey,
 | 
				
			||||||
                                      long nonceTrialsPerByte, long extraBytes, Pubkey.Feature... features) {
 | 
					                                      long nonceTrialsPerByte, long extraBytes, Pubkey.Feature... features) {
 | 
				
			||||||
        return Factory.createPubkey(version, stream,
 | 
					        return Factory.createPubkey(version, stream,
 | 
				
			||||||
@@ -164,10 +268,18 @@ public class Security {
 | 
				
			|||||||
                nonceTrialsPerByte, extraBytes, features);
 | 
					                nonceTrialsPerByte, extraBytes, features);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @param privateKey private key as byte array
 | 
				
			||||||
 | 
					     * @return a public key corresponding to the given private key
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    public static ECPoint createPublicKey(byte[] privateKey) {
 | 
					    public static ECPoint createPublicKey(byte[] privateKey) {
 | 
				
			||||||
        return EC_CURVE_PARAMETERS.getG().multiply(keyToBigInt(privateKey)).normalize();
 | 
					        return EC_CURVE_PARAMETERS.getG().multiply(keyToBigInt(privateKey)).normalize();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @param privateKey private key as byte array
 | 
				
			||||||
 | 
					     * @return a big integer representation (unsigned) of the given bytes
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    public static BigInteger keyToBigInt(byte[] privateKey) {
 | 
					    public static BigInteger keyToBigInt(byte[] privateKey) {
 | 
				
			||||||
        return new BigInteger(1, privateKey);
 | 
					        return new BigInteger(1, privateKey);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -185,7 +297,13 @@ public class Security {
 | 
				
			|||||||
        );
 | 
					        );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static boolean isSignatureValid(byte[] bytesToSign, byte[] signature, Pubkey pubkey) {
 | 
					    /**
 | 
				
			||||||
 | 
					     * @param data      to check
 | 
				
			||||||
 | 
					     * @param signature the signature of the message
 | 
				
			||||||
 | 
					     * @param pubkey    the sender's public key
 | 
				
			||||||
 | 
					     * @return true if the signature is valid, false otherwise
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public static boolean isSignatureValid(byte[] data, byte[] signature, Pubkey pubkey) {
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
            ECParameterSpec spec = new ECParameterSpec(
 | 
					            ECParameterSpec spec = new ECParameterSpec(
 | 
				
			||||||
                    EC_CURVE_PARAMETERS.getCurve(),
 | 
					                    EC_CURVE_PARAMETERS.getCurve(),
 | 
				
			||||||
@@ -201,13 +319,20 @@ public class Security {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            Signature sig = Signature.getInstance("ECDSA", "BC");
 | 
					            Signature sig = Signature.getInstance("ECDSA", "BC");
 | 
				
			||||||
            sig.initVerify(publicKey);
 | 
					            sig.initVerify(publicKey);
 | 
				
			||||||
            sig.update(bytesToSign);
 | 
					            sig.update(data);
 | 
				
			||||||
            return sig.verify(signature);
 | 
					            return sig.verify(signature);
 | 
				
			||||||
        } catch (Exception e) {
 | 
					        } catch (Exception e) {
 | 
				
			||||||
            throw new RuntimeException(e);
 | 
					            throw new RuntimeException(e);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Calculate the signature of data, using the given private key.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param data       to be signed
 | 
				
			||||||
 | 
					     * @param privateKey to be used for signing
 | 
				
			||||||
 | 
					     * @return the signature
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    public static byte[] getSignature(byte[] data, ch.dissem.bitmessage.entity.valueobject.PrivateKey privateKey) {
 | 
					    public static byte[] getSignature(byte[] data, ch.dissem.bitmessage.entity.valueobject.PrivateKey privateKey) {
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
            ECParameterSpec spec = new ECParameterSpec(
 | 
					            ECParameterSpec spec = new ECParameterSpec(
 | 
				
			||||||
@@ -231,6 +356,9 @@ public class Security {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @return a random number of type long
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    public static long randomNonce() {
 | 
					    public static long randomNonce() {
 | 
				
			||||||
        return RANDOM.nextLong();
 | 
					        return RANDOM.nextLong();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -30,7 +30,7 @@ public class UnixTime {
 | 
				
			|||||||
    public static final long DAY = 24 * HOUR;
 | 
					    public static final long DAY = 24 * HOUR;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Returns the time in second based Unix time ({@link System#currentTimeMillis()}/1000)
 | 
					     * @return the time in second based Unix time ({@link System#currentTimeMillis()}/1000)
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public static long now() {
 | 
					    public static long now() {
 | 
				
			||||||
        return System.currentTimeMillis() / 1000;
 | 
					        return System.currentTimeMillis() / 1000;
 | 
				
			||||||
@@ -38,6 +38,9 @@ public class UnixTime {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Same as {@link #now()} + shiftSeconds, but might be more readable.
 | 
					     * Same as {@link #now()} + shiftSeconds, but might be more readable.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param shiftSeconds number of seconds from now we're interested in
 | 
				
			||||||
 | 
					     * @return the Unix time in shiftSeconds seconds / shiftSeconds seconds ago
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public static long now(long shiftSeconds) {
 | 
					    public static long now(long shiftSeconds) {
 | 
				
			||||||
        return (System.currentTimeMillis() / 1000) + shiftSeconds;
 | 
					        return (System.currentTimeMillis() / 1000) + shiftSeconds;
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user