public static byte[] calculateTag(long version, long stream, byte[] ripe) { try { ByteArrayOutputStream out = new ByteArrayOutputStream(); Encode.varInt(version, out); Encode.varInt(stream, out); out.write(ripe); return Arrays.copyOfRange(Security.doubleSha512(out.toByteArray()), 32, 64); } catch (IOException e) { throw new RuntimeException(e); } }
BitmessageAddress(long version, long stream, byte[] ripe) { try { this.version = version; this.stream = stream; this.ripe = ripe; ByteArrayOutputStream os = new ByteArrayOutputStream(); Encode.varInt(version, os); Encode.varInt(stream, os); if (version < 4) { byte[] checksum = Security.sha512(os.toByteArray(), ripe); this.tag = null; this.publicDecryptionKey = Arrays.copyOfRange(checksum, 0, 32); } else { // for tag and decryption key, the checksum has to be created with 0x00 padding byte[] checksum = Security.doubleSha512(os.toByteArray(), ripe); this.tag = Arrays.copyOfRange(checksum, 32, 64); this.publicDecryptionKey = Arrays.copyOfRange(checksum, 0, 32); } // but for the address and its checksum they need to be stripped int offset = Bytes.numberOfLeadingZeros(ripe); os.write(ripe, offset, ripe.length - offset); byte[] checksum = Security.doubleSha512(os.toByteArray()); os.write(checksum, 0, 4); this.address = "BM-" + Base58.encode(os.toByteArray()); } catch (IOException e) { throw new RuntimeException(e); } }
public InventoryVector getInventoryVector() { return new InventoryVector(Bytes.truncate(Security.doubleSha512(nonce, getPayloadBytesWithoutNonce()), 32)); }
public BitmessageAddress(String address) { try { this.address = address; byte[] bytes = Base58.decode(address.substring(3)); ByteArrayInputStream in = new ByteArrayInputStream(bytes); AccessCounter counter = new AccessCounter(); this.version = varInt(in, counter); this.stream = varInt(in, counter); this.ripe = Bytes.expand(bytes(in, bytes.length - counter.length() - 4), 20); // test checksum byte[] checksum = Security.doubleSha512(bytes, bytes.length - 4); byte[] expectedChecksum = bytes(in, 4); for (int i = 0; i < 4; i++) { if (expectedChecksum[i] != checksum[i]) throw new IllegalArgumentException("Checksum of address failed"); } if (version < 4) { checksum = Security.sha512(Arrays.copyOfRange(bytes, 0, counter.length()), ripe); this.tag = null; this.publicDecryptionKey = Arrays.copyOfRange(checksum, 0, 32); } else { checksum = Security.doubleSha512(Arrays.copyOfRange(bytes, 0, counter.length()), ripe); this.tag = Arrays.copyOfRange(checksum, 32, 64); this.publicDecryptionKey = Arrays.copyOfRange(checksum, 0, 32); } } catch (IOException e) { throw new RuntimeException(e); } }
/** * @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 { byte[] target = getProofOfWorkTarget(object, nonceTrialsPerByte, extraBytes); byte[] value = Security.doubleSha512(object.getNonce(), getInitialHash(object)); if (Bytes.lt(target, value, 8)) { throw new InsufficientProofOfWorkException(target, value); } }