/** * Generates a new key chain with entropy selected randomly from the given {@link java.security.SecureRandom} * object and of the requested size in bits. */ public DeterministicKeyChain(SecureRandom random, int bits) { this(random, bits, DEFAULT_PASSPHRASE_FOR_MNEMONIC, Utils.currentTimeSeconds()); }
private void checkTimestamp() throws VerificationException { final long allowedTime = Utils.currentTimeSeconds() + ALLOWED_TIME_DRIFT; if (time > allowedTime) throw new VerificationException(String.format(Locale.US, "Block too far in future: %s (%d) vs allowed %s (%d)", Utils.dateTimeFormat(time * 1000), time, Utils.dateTimeFormat(allowedTime * 1000), allowedTime)); }
public AbstractLitecoinParams() { super(); interval = LITE_INTERVAL; targetTimespan = LITE_TARGET_TIMESPAN; maxTarget = Utils.decodeCompactBits(0x1e0fffffL); packetMagic = 0xfbc0b6db; bip32HeaderPub = 0x0488C42E; //The 4 byte header that serializes in base58 to "xpub". (?) bip32HeaderPriv = 0x0488E1F4; //The 4 byte header that serializes in base58 to "xprv" (?) }
@Override protected void bitcoinSerializeToStream(OutputStream stream) throws IOException { stream.write(new VarInt(hashes.size()).encode()); for (Sha256Hash hash: hashes) { stream.write(Utils.reverseBytes(hash.getBytes())); } Utils.uint32ToByteStreamLE(index, stream); }
stack.add(Utils.reverseBytes(Utils.encodeMPI(BigInteger.ONE.negate(), false))); break; case OP_1: case OP_15: case OP_16: stack.add(Utils.reverseBytes(Utils.encodeMPI(BigInteger.valueOf(decodeFromOpN(opcode)), false))); break; case OP_NOP: break; case OP_DEPTH: stack.add(Utils.reverseBytes(Utils.encodeMPI(BigInteger.valueOf(stack.size()), false))); break; case OP_DROP: if (stack.size() < 1) throw new ScriptException("Attempted OP_SIZE on an empty stack"); stack.add(Utils.reverseBytes(Utils.encodeMPI(BigInteger.valueOf(stack.getLast().length), false))); break; case OP_INVERT: stack.add(Utils.reverseBytes(Utils.encodeMPI(numericOPnum, false))); break; case OP_2MUL: stack.add(Utils.reverseBytes(Utils.encodeMPI(numericOPresult, false))); break; case OP_MUL:
BigInteger newTarget = Utils.decodeCompactBits(lastDifficultyTarget); newTarget = newTarget.multiply(BigInteger.valueOf(actualTime)); newTarget = newTarget.divide(BigInteger.valueOf(retargetTimespan)); return Utils.encodeCompactBits(newTarget);
public static Script createCLTVPaymentChannelOutput(BigInteger time, ECKey from, ECKey to) { byte[] timeBytes = Utils.reverseBytes(Utils.encodeMPI(time, false)); if (timeBytes.length > 5) { throw new RuntimeException("Time too large to encode as 5-byte int"); } return new ScriptBuilder().op(OP_IF) .data(to.getPubKey()).op(OP_CHECKSIGVERIFY) .op(OP_ELSE) .data(timeBytes).op(OP_CHECKLOCKTIMEVERIFY).op(OP_DROP) .op(OP_ENDIF) .data(from.getPubKey()).op(OP_CHECKSIG).build(); }
/** Gets the hash160 form of the public key (as seen in addresses). */ public byte[] getPubKeyHash() { if (pubKeyHash == null) pubKeyHash = Utils.sha256hash160(this.pub.getEncoded()); return pubKeyHash; }
/** * Called when download progress is made. * * @param pct the percentage of chain downloaded, estimated * @param date the date of the last block downloaded */ protected void progress(double pct, int blocksSoFar, Date date) { log.info(String.format(Locale.US, "Chain download %d%% done with %d blocks to go, block date %s", (int) pct, blocksSoFar, Utils.dateTimeFormat(date))); }
/** * Signs a text message using the standard Bitcoin messaging signing format and returns the signature as a base64 * encoded string. * * @throws IllegalStateException if this ECKey does not have the private part. * @throws KeyCrypterException if this ECKey is encrypted and no AESKey is provided or it does not decrypt the ECKey. */ public String signMessage(String message, @Nullable KeyParameter aesKey) throws KeyCrypterException { byte[] data = Utils.formatMessageForSigning(message); Sha256Hash hash = Sha256Hash.twiceOf(data); ECDSASignature sig = sign(hash, aesKey); // Now we have to work backwards to figure out the recId needed to recover the signature. int recId = -1; for (int i = 0; i < 4; i++) { ECKey k = ECKey.recoverFromSignature(i, sig, hash, isCompressed()); if (k != null && k.pub.equals(pub)) { recId = i; break; } } if (recId == -1) throw new RuntimeException("Could not construct a recoverable key. This should never happen."); int headerByte = recId + 27 + (isCompressed() ? 4 : 0); byte[] sigData = new byte[65]; // 1 header + 32 bytes for R + 32 bytes for S sigData[0] = (byte)headerByte; System.arraycopy(Utils.bigIntegerToBytes(sig.r, 32), 0, sigData, 1, 32); System.arraycopy(Utils.bigIntegerToBytes(sig.s, 32), 0, sigData, 33, 32); return new String(Base64.encode(sigData), Charset.forName("UTF-8")); }
/** * Called by a {@link Peer} when a transaction is pending and announced by a peer. The more peers announce the * transaction, the more peers have validated it (assuming your internet connection is not being intercepted). * If confidence is currently unknown, sets it to {@link ConfidenceType#PENDING}. Does not run listeners. * * @param address IP address of the peer, used as a proxy for identity. * @return true if marked, false if this address was already seen */ public boolean markBroadcastBy(PeerAddress address) { lastBroadcastedAt = Utils.now(); if (!broadcastBy.addIfAbsent(address)) return false; // Duplicate. synchronized (this) { if (getConfidenceType() == ConfidenceType.UNKNOWN) { this.confidenceType = ConfidenceType.PENDING; } } return true; }
/** * Returns a reversed copy of the internal byte array. */ public byte[] getReversedBytes() { return Utils.reverseBytes(bytes); }
/** Track a success - reset back off interval to the initial value */ public final void trackSuccess() { backoff = params.initial; retryTime = Utils.currentTimeMillis(); }
@Test public void keyRotationRandom() throws Exception { Utils.setMockClock(); key1.setCreationTimeSeconds(Utils.currentTimeSeconds() - (86400 * 2)); ECKey key2 = new ECKey(); key2.setCreationTimeSeconds(Utils.currentTimeSeconds() - 86400); wallet.importKey(key1); wallet.importKey(key2); sendMoneyToWallet(wallet, AbstractBlockChain.NewBlockType.BEST_CHAIN, CENT, key2.toAddress(PARAMS)); sendMoneyToWallet(wallet, AbstractBlockChain.NewBlockType.BEST_CHAIN, CENT, key2.toAddress(PARAMS)); Date compromiseTime = Utils.now(); assertEquals(0, broadcaster.size()); assertFalse(wallet.isKeyRotating(key1)); Utils.rollMockClock(1); wallet.setKeyRotationTime(compromiseTime); assertTrue(wallet.isKeyRotating(key1));
void verifyDifficulty(BigInteger newTarget, Block nextBlock) { if (newTarget.compareTo(this.getMaxTarget()) > 0) { log.info("Difficulty hit proof of work limit: {}", newTarget.toString(16)); newTarget = this.getMaxTarget(); } int accuracyBytes = (int) (nextBlock.getDifficultyTarget() >>> 24) - 3; long receivedTargetCompact = nextBlock.getDifficultyTarget(); // The calculated difficulty is to a higher precision than received, so reduce here. BigInteger mask = BigInteger.valueOf(0xFFFFFFL).shiftLeft(accuracyBytes * 8); newTarget = newTarget.and(mask); long newTargetCompact = Utils.encodeCompactBits(newTarget); if (newTargetCompact != receivedTargetCompact) throw new VerificationException("Network provided difficulty bits do not match what was calculated: " + Long.toHexString(newTargetCompact) + " vs " + Long.toHexString(receivedTargetCompact)); }
@Test public void serializationUnencrypted() throws UnreadableWalletException { Utils.setMockClock(); Date now = Utils.now(); final ECKey key1 = new ECKey(); Utils.rollMockClock(5000); final ECKey key2 = new ECKey(); chain.importKeys(ImmutableList.of(key1, key2)); List<Protos.Key> keys = chain.serializeToProtobuf(); assertEquals(2, keys.size()); assertArrayEquals(key1.getPubKey(), keys.get(0).getPublicKey().toByteArray()); assertArrayEquals(key2.getPubKey(), keys.get(1).getPublicKey().toByteArray()); assertArrayEquals(key1.getPrivKeyBytes(), keys.get(0).getSecretBytes().toByteArray()); assertArrayEquals(key2.getPrivKeyBytes(), keys.get(1).getSecretBytes().toByteArray()); long normTime = (long) (Math.floor(now.getTime() / 1000) * 1000); assertEquals(normTime, keys.get(0).getCreationTimestamp()); assertEquals(normTime + 5000 * 1000, keys.get(1).getCreationTimestamp()); chain = BasicKeyChain.fromProtobufUnencrypted(keys); assertEquals(2, chain.getKeys().size()); assertEquals(key1, chain.getKeys().get(0)); assertEquals(key2, chain.getKeys().get(1)); }
public static boolean verifyMessage(byte [] pubkeyId, MasternodeSignature vchSig, String message, StringBuilder errorMessage) { byte [] dataToHash = Utils.formatMessageForSigning(message); return HashSigner.verifyHash(Sha256Hash.twiceOf(dataToHash), pubkeyId, vchSig, errorMessage); } }
public static boolean verifyMessage1(PublicKey pubkey, MasternodeSignature vchSig, byte[] message, StringBuilder errorMessage) { //int length = Utils.BITCOIN_SIGNED_MESSAGE_HEADER.length()+strMessage.length(); byte dataToHash []; // = (Utils.BITCOIN_SIGNED_MESSAGE_HEADER_BYTES+strMessage).getBytes(); //ByteOutputStream bos = new ByteOutputStream(message.length + Utils.BITCOIN_SIGNED_MESSAGE_HEADER_BYTES.length); //bos.write(Utils.BITCOIN_SIGNED_MESSAGE_HEADER_BYTES); //bos.write(message); dataToHash = Utils.formatMessageForSigning(message);//bos.getBytes(); //PublicKey pubkey2; ECKey pubkey2 = null; try { // pubkey2 = PublicKey.recoverCompact(Sha256Hash.twiceOf(dataToHash), vchSig); //ECKey.verify() //if(DarkCoinSystem.fDebug && !pubkey.getId().equals(pubkey2.getId())); // log.info("DarkSendSigner.verifyMessage -- keys don't match: " + pubkey2.getId().toString()+ " " + pubkey.getId().toString()); //return pubkey.getId().equals(pubkey2.getId()); //return true; pubkey2 = ECKey.fromPublicOnly(pubkey.getBytes()); pubkey2.verifyMessage(message, vchSig.getBytes()); return true; } catch(SignatureException x) { errorMessage.append("keys don't match - input: "+Utils.HEX.encode(pubkey.getId())); errorMessage.append(", recovered: " + (pubkey2 != null ? Utils.HEX.encode(pubkey2.getPubKeyHash()) : "null")); errorMessage.append(", message: "+ Utils.sanitizeString(new String(message))); errorMessage.append(", sig: not impl!\n" + x.getMessage()); return false; } }
stack.add(Utils.reverseBytes(Utils.encodeMPI(BigInteger.ONE.negate(), false))); break; case OP_1: case OP_15: case OP_16: stack.add(Utils.reverseBytes(Utils.encodeMPI(BigInteger.valueOf(decodeFromOpN(opcode)), false))); break; case OP_NOP: break; case OP_DEPTH: stack.add(Utils.reverseBytes(Utils.encodeMPI(BigInteger.valueOf(stack.size()), false))); break; case OP_DROP: if (stack.size() < 1) throw new ScriptException(ScriptError.SCRIPT_ERR_INVALID_STACK_OPERATION, "Attempted OP_SIZE on an empty stack"); stack.add(Utils.reverseBytes(Utils.encodeMPI(BigInteger.valueOf(stack.getLast().length), false))); break; case OP_EQUAL: stack.add(Utils.reverseBytes(Utils.encodeMPI(numericOPnum, false))); break; case OP_ADD: stack.add(Utils.reverseBytes(Utils.encodeMPI(numericOPresult, false))); break; case OP_NUMEQUALVERIFY:
@Test public void compactEncoding() throws Exception { assertEquals(new BigInteger("1234560000", 16), Utils.decodeCompactBits(0x05123456L)); assertEquals(new BigInteger("c0de000000", 16), Utils.decodeCompactBits(0x0600c0de)); assertEquals(0x05123456L, Utils.encodeCompactBits(new BigInteger("1234560000", 16))); assertEquals(0x0600c0deL, Utils.encodeCompactBits(new BigInteger("c0de000000", 16))); }