use of io.nuls.core.tools.crypto.UnsafeByteArrayOutputStream in project nuls by nuls-io.
the class Script method createInputScript.
/**
* 根据签名的字节数组转为inputScript/scriptSig 字节数组用于网络传播
*/
public static byte[] createInputScript(byte[] signature) {
try {
// TODO: Do this by creating a Script *first* then having the script reassemble itself into bytes.
ByteArrayOutputStream bits = new UnsafeByteArrayOutputStream(signature.length + 2);
writeBytes(bits, signature);
return bits.toByteArray();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
use of io.nuls.core.tools.crypto.UnsafeByteArrayOutputStream in project nuls by nuls-io.
the class Script method executeMultiSig.
private static int executeMultiSig(Transaction txContainingThis, int index, Script script, LinkedList<byte[]> stack, int opCount, int lastCodeSepLocation, int opcode, Set<VerifyFlag> verifyFlags) throws ScriptException {
final boolean requireCanonical = verifyFlags.contains(VerifyFlag.STRICTENC) || verifyFlags.contains(VerifyFlag.DERSIG) || verifyFlags.contains(VerifyFlag.LOW_S);
if (stack.size() < 2) {
throw new ScriptException("Attempted OP_CHECKMULTISIG(VERIFY) on a stack with size < 2");
}
int pubKeyCount = castToBigInteger(stack.pollLast()).intValue();
if (pubKeyCount < 0 || pubKeyCount > 20) {
throw new ScriptException("OP_CHECKMULTISIG(VERIFY) with pubkey count out of range");
}
opCount += pubKeyCount;
if (opCount > 201) {
throw new ScriptException("Total op count > 201 during OP_CHECKMULTISIG(VERIFY)");
}
if (stack.size() < pubKeyCount + 1) {
throw new ScriptException("Attempted OP_CHECKMULTISIG(VERIFY) on a stack with size < num_of_pubkeys + 2");
}
LinkedList<byte[]> pubkeys = new LinkedList<byte[]>();
for (int i = 0; i < pubKeyCount; i++) {
byte[] pubKey = stack.pollLast();
pubkeys.add(pubKey);
}
int sigCount = castToBigInteger(stack.pollLast()).intValue();
if (sigCount < 0 || sigCount > pubKeyCount) {
throw new ScriptException("OP_CHECKMULTISIG(VERIFY) with sig count out of range");
}
if (stack.size() < sigCount + 1) {
throw new ScriptException("Attempted OP_CHECKMULTISIG(VERIFY) on a stack with size < num_of_pubkeys + num_of_signatures + 3");
}
LinkedList<byte[]> sigs = new LinkedList<byte[]>();
for (int i = 0; i < sigCount; i++) {
byte[] sig = stack.pollLast();
sigs.add(sig);
}
byte[] prog = script.getProgram();
byte[] connectedScript = Arrays.copyOfRange(prog, lastCodeSepLocation, prog.length);
for (byte[] sig : sigs) {
UnsafeByteArrayOutputStream outStream = new UnsafeByteArrayOutputStream(sig.length + 1);
try {
writeBytes(outStream, sig);
} catch (IOException e) {
// Cannot happen
throw new RuntimeException(e);
}
connectedScript = removeAllInstancesOf(connectedScript, outStream.toByteArray());
}
boolean valid = true;
while (sigs.size() > 0) {
byte[] pubKey = pubkeys.pollFirst();
// more expensive than hashing, its not a big deal.
try {
if (ECKey.verify(txContainingThis.getHash().getDigestBytes(), sigs.getFirst(), pubKey)) {
sigs.pollFirst();
}
/* TransactionSignature sig = TransactionSignature.decodeFromBitcoin(sigs.getFirst(), requireCanonical);
Sha256Hash hash = txContainingThis.hashForSignature(index, connectedScript, (byte) sig.sighashFlags);
if (ECKey.verify(hash.getBytes(), sig, pubKey))
sigs.pollFirst();*/
} catch (Exception e) {
// There is (at least) one exception that could be hit here (EOFException, if the sig is too short)
// Because I can't verify there aren't more, we use a very generic Exception catch
e.printStackTrace();
}
if (sigs.size() > pubkeys.size()) {
valid = false;
break;
}
}
// We uselessly remove a stack object to emulate a Bitcoin Core bug.
byte[] nullDummy = stack.pollLast();
if (verifyFlags.contains(VerifyFlag.NULLDUMMY) && nullDummy.length > 0) {
throw new ScriptException("OP_CHECKMULTISIG(VERIFY) with non-null nulldummy: " + Arrays.toString(nullDummy));
}
if (opcode == OP_CHECKMULTISIG) {
stack.add(valid ? new byte[] { 1 } : new byte[] {});
} else if (opcode == OP_CHECKMULTISIGVERIFY) {
if (!valid) {
throw new ScriptException("Script failed OP_CHECKMULTISIGVERIFY");
}
}
return opCount;
}
use of io.nuls.core.tools.crypto.UnsafeByteArrayOutputStream in project nuls by nuls-io.
the class Script method executeCheckSig.
private static void executeCheckSig(Transaction txContainingThis, int index, Script script, LinkedList<byte[]> stack, int lastCodeSepLocation, int opcode, Set<VerifyFlag> verifyFlags) throws ScriptException {
final boolean requireCanonical = verifyFlags.contains(VerifyFlag.STRICTENC) || verifyFlags.contains(VerifyFlag.DERSIG) || verifyFlags.contains(VerifyFlag.LOW_S);
if (stack.size() < 2) {
throw new ScriptException("Attempted OP_CHECKSIG(VERIFY) on a stack with size < 2");
}
byte[] pubKey = stack.pollLast();
byte[] sigBytes = stack.pollLast();
byte[] prog = script.getProgram();
byte[] connectedScript = Arrays.copyOfRange(prog, lastCodeSepLocation, prog.length);
UnsafeByteArrayOutputStream outStream = new UnsafeByteArrayOutputStream(sigBytes.length + 1);
try {
writeBytes(outStream, sigBytes);
} catch (IOException e) {
// Cannot happen
throw new RuntimeException(e);
}
connectedScript = removeAllInstancesOf(connectedScript, outStream.toByteArray());
// TODO: Use int for indexes everywhere, we can't have that many inputs/outputs
boolean sigValid = false;
try {
sigValid = verifySign(txContainingThis.getHash().getDigestBytes(), sigBytes, pubKey);
/*ransactionSignature sig = TransactionSignature.decodeFromBitcoin(sigBytes, requireCanonical,
verifyFlags.contains(VerifyFlag.LOW_S));
// TODO: Should check hash type is known
Sha256Hash hash = txContainingThis.hashForSignature(index, connectedScript, (byte) sig.sighashFlags);
sigValid = ECKey.verify(hash.getBytes(), sig, pubKey);*/
} catch (Exception e1) {
// signing work to be done inside LocalTransactionSigner.signInputs.
if (!e1.getMessage().contains("Reached past end of ASN.1 stream")) {
log.warn("Signature checking failed!", e1);
}
}
// System.out.println(opcode == OP_CHECKSIG);
if (opcode == OP_CHECKSIG) {
stack.add(sigValid ? new byte[] { 1 } : new byte[] {});
} else if (opcode == OP_CHECKSIGVERIFY) {
if (!sigValid) {
throw new ScriptException("Script failed OP_CHECKSIGVERIFY");
}
}
}
use of io.nuls.core.tools.crypto.UnsafeByteArrayOutputStream in project nuls by nuls-io.
the class BaseNulsData method serialize.
@Override
public final byte[] serialize() throws IOException {
ByteArrayOutputStream bos = null;
try {
int size = size();
bos = new UnsafeByteArrayOutputStream(size);
NulsOutputStreamBuffer buffer = new NulsOutputStreamBuffer(bos);
if (size == 0) {
bos.write(NulsConstant.PLACE_HOLDER);
} else {
serializeToStream(buffer);
}
byte[] bytes = bos.toByteArray();
if (bytes.length != this.size()) {
throw new NulsRuntimeException(KernelErrorCode.SERIALIZE_ERROR);
}
return bytes;
} finally {
if (bos != null) {
try {
bos.close();
} catch (IOException e) {
throw e;
}
}
}
}
use of io.nuls.core.tools.crypto.UnsafeByteArrayOutputStream in project nuls by nuls-io.
the class Transaction method serializeForHash.
public byte[] serializeForHash() throws IOException {
ByteArrayOutputStream bos = null;
try {
int size = size() - SerializeUtils.sizeOfBytes(transactionSignature);
bos = new UnsafeByteArrayOutputStream(size);
NulsOutputStreamBuffer buffer = new NulsOutputStreamBuffer(bos);
do {
if (size == 0) {
bos.write(NulsConstant.PLACE_HOLDER);
break;
}
if (NulsContext.MAIN_NET_VERSION < 2) {
buffer.writeVarInt(type);
buffer.writeVarInt(time);
break;
}
if (this.blockHeight == -1) {
buffer.writeUint16(type);
buffer.writeUint48(time);
break;
}
if (NulsContext.CHANGE_HASH_SERIALIZE_HEIGHT == null || this.blockHeight >= NulsContext.CHANGE_HASH_SERIALIZE_HEIGHT) {
buffer.writeUint16(type);
buffer.writeUint48(time);
} else {
buffer.writeVarInt(type);
buffer.writeVarInt(time);
}
} while (false);
if (size > 0) {
buffer.writeBytesWithLength(remark);
buffer.writeNulsData(txData);
buffer.writeNulsData(coinData);
}
return bos.toByteArray();
} finally {
if (bos != null) {
try {
bos.close();
} catch (IOException e) {
throw e;
}
}
}
}
Aggregations