From e97ae1dd2e9f14d6076d5e5429c75d8965afa4ab Mon Sep 17 00:00:00 2001 From: Simon Date: Sun, 28 Oct 2018 14:48:10 -0700 Subject: [PATCH] Add fix for v4 joinsplits using Groth16 proof. Closes https://github.com/zcash/zcash/issues/3636 where a tx with multiple joinsplits would not be parsed correctly. --- lib/transaction/jsdescription.js | 24 ++++++++++++++++++------ lib/transaction/transaction.js | 3 ++- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/lib/transaction/jsdescription.js b/lib/transaction/jsdescription.js index 3ab72eb..efa8621 100644 --- a/lib/transaction/jsdescription.js +++ b/lib/transaction/jsdescription.js @@ -8,7 +8,8 @@ var BufferWriter = require('../encoding/bufferwriter'); var BufferUtil = require('../util/buffer'); var JSUtil = require('../util/js'); -var ZCProof = require('../zcash/proof'); +// TODO: Update ZCProof for Groth +//var ZCProof = require('../zcash/proof'); var ZC_NUM_JS_INPUTS = 2; var ZC_NUM_JS_OUTPUTS = 2; @@ -117,7 +118,7 @@ JSDescription.prototype._fromObject = function(params) { this.ciphertexts = ciphertexts; this.randomSeed = BufferUtil.reverse(new buffer.Buffer(params.randomSeed, 'hex')); this.macs = macs; - this.proof = ZCProof.fromObject(params.proof); + this.proof = params.proof; // TODO: Update ZCProof for Groth: ZCProof.fromObject(params.proof); return this; }; @@ -148,12 +149,12 @@ JSDescription.prototype.toObject = JSDescription.prototype.toJSON = function toO ciphertexts: ciphertexts, randomSeed: BufferUtil.reverse(this.randomSeed).toString('hex'), macs: macs, - proof: this.proof.toObject(), + proof: this.proof, // TODO: Update ZCProof for Groth: this.proof.toObject(), }; return obj; }; -JSDescription.fromBufferReader = function(br) { +JSDescription.fromBufferReader = function(br, useGrothFlagParam) { var i; var jsdesc = new JSDescription(); jsdesc.vpub_old = br.readUInt64LEBN(); @@ -170,7 +171,15 @@ JSDescription.fromBufferReader = function(br) { for (i = 0; i < ZC_NUM_JS_INPUTS; i++) { jsdesc.macs.push(br.read(32)); } - jsdesc.proof = ZCProof.fromBufferReader(br); + + // Default parameter requires ECMASCript 6 which might not be available, so use workaround. + var useGrothFlag = useGrothFlagParam || false; + if (!useGrothFlag) { + jsdesc.proof = br.read(296); // TODO: Update ZCProof for Groth: ZCProof.fromBufferReader(br); + } else { + jsdesc.proof = br.read(48 + 96 + 48); + } + for (i = 0; i < ZC_NUM_JS_OUTPUTS; i++) { jsdesc.ciphertexts.push(br.read(ZC_NOTECIPHERTEXT_SIZE)); } @@ -196,7 +205,10 @@ JSDescription.prototype.toBufferWriter = function(writer) { for (i = 0; i < ZC_NUM_JS_INPUTS; i++) { writer.write(this.macs[i]); } - this.proof.toBufferWriter(writer); + + // TODO: Update ZCProof for Groth: this.proof.toBufferWriter(writer); + writer.write(this.proof); + for (i = 0; i < ZC_NUM_JS_OUTPUTS; i++) { writer.write(this.ciphertexts[i]); } diff --git a/lib/transaction/transaction.js b/lib/transaction/transaction.js index 0805926..af90a0a 100644 --- a/lib/transaction/transaction.js +++ b/lib/transaction/transaction.js @@ -396,10 +396,11 @@ Transaction.prototype.fromBufferReader = function(reader) { } } + var useGrothFlag = (this.version >= 4); if (this.version >= 2) { sizeJSDescs = reader.readVarintNum(); for (i = 0; i < sizeJSDescs; i++) { - this.joinSplits.push(JSDescription.fromBufferReader(reader)); + this.joinSplits.push(JSDescription.fromBufferReader(reader, useGrothFlag)); } if (sizeJSDescs > 0) { this.joinSplitPubKey = reader.read(32);