Skip to content

Commit 305c6e4

Browse files
committed
fix(crypto): harden shielded transaction safety and input validation
1 parent 3ab5adf commit 305c6e4

7 files changed

Lines changed: 241 additions & 50 deletions

File tree

actuator/src/main/java/org/tron/core/vm/PrecompiledContracts.java

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1148,8 +1148,8 @@ public abstract static class VerifyProof extends PrecompiledContract {
11481148
new LibrustzcashParam.MerkleHashParams(
11491149
i, UNCOMMITTED[i], UNCOMMITTED[i], UNCOMMITTED[i + 1]));
11501150
}
1151-
} catch (Throwable any) {
1152-
logger.info("Initialize UNCOMMITTED array failed:{}", any.getMessage());
1151+
} catch (ZksnarkException e) {
1152+
throw new RuntimeException("Failed to initialize UNCOMMITTED array", e);
11531153
}
11541154
}
11551155

@@ -1258,7 +1258,7 @@ protected Pair<Boolean, byte[]> insertLeaves(
12581258
if (success) {
12591259
return Pair.of(true, merge(DataWord.ONE().getData(), result));
12601260
} else {
1261-
return Pair.of(true, DataWord.ZERO().getData());
1261+
return Pair.of(false, EMPTY_BYTE_ARRAY);
12621262
}
12631263
}
12641264
}
@@ -1282,6 +1282,10 @@ public Pair<Boolean, byte[]> execute(byte[] data) {
12821282
}
12831283
boolean result;
12841284
long ctx = JLibrustzcash.librustzcashSaplingVerificationCtxInit();
1285+
if (ctx == 0) {
1286+
logger.info("VerifyMintProof: failed to init verification context");
1287+
return Pair.of(false, EMPTY_BYTE_ARRAY);
1288+
}
12851289
try {
12861290
byte[] cm = new byte[32];
12871291
byte[] cv = new byte[32];
@@ -1328,7 +1332,7 @@ public Pair<Boolean, byte[]> execute(byte[] data) {
13281332
} finally {
13291333
JLibrustzcash.librustzcashSaplingVerificationCtxFree(ctx);
13301334
}
1331-
return Pair.of(true, DataWord.ZERO().getData());
1335+
return Pair.of(false, EMPTY_BYTE_ARRAY);
13321336
}
13331337
}
13341338

@@ -1477,6 +1481,10 @@ public Pair<Boolean, byte[]> execute(byte[] data) {
14771481

14781482
boolean withNoTimeout = countDownLatch.await(getCPUTimeLeftInNanoSecond(),
14791483
TimeUnit.NANOSECONDS);
1484+
if (!withNoTimeout) {
1485+
futures.forEach(f -> f.cancel(true));
1486+
return Pair.of(true, DataWord.ZERO().getData());
1487+
}
14801488
boolean checkResult = true;
14811489
for (Future<Boolean> future : futures) {
14821490
boolean eachTaskResult = future.get();
@@ -1497,7 +1505,7 @@ public Pair<Boolean, byte[]> execute(byte[] data) {
14971505
}
14981506
logger.info("VerifyTransferProof exception: " + errorMsg);
14991507
}
1500-
return Pair.of(true, DataWord.ZERO().getData());
1508+
return Pair.of(false, EMPTY_BYTE_ARRAY);
15011509
}
15021510

15031511
private static class SaplingCheckSpendTask implements Callable<Boolean> {
@@ -1527,17 +1535,13 @@ private static class SaplingCheckSpendTask implements Callable<Boolean> {
15271535

15281536
@Override
15291537
public Boolean call() throws ZksnarkException {
1530-
boolean result;
15311538
try {
1532-
result = JLibrustzcash.librustzcashSaplingCheckSpendNew(
1539+
return JLibrustzcash.librustzcashSaplingCheckSpendNew(
15331540
new LibrustzcashParam.CheckSpendNewParams(this.cv, this.anchor, this.nullifier,
15341541
this.rk, this.zkproof, this.spendAuthSig, this.signHash));
1535-
} catch (ZksnarkException e) {
1536-
throw e;
15371542
} finally {
15381543
countDownLatch.countDown();
15391544
}
1540-
return result;
15411545
}
15421546
}
15431547

@@ -1561,17 +1565,13 @@ private static class SaplingCheckOutputTask implements Callable<Boolean> {
15611565

15621566
@Override
15631567
public Boolean call() throws ZksnarkException {
1564-
boolean result;
15651568
try {
1566-
result = JLibrustzcash.librustzcashSaplingCheckOutputNew(
1569+
return JLibrustzcash.librustzcashSaplingCheckOutputNew(
15671570
new LibrustzcashParam.CheckOutputNewParams(this.cv, this.cm,
15681571
this.ephemeralKey, this.zkproof));
1569-
} catch (ZksnarkException e) {
1570-
throw e;
15711572
} finally {
15721573
countDownLatch.countDown();
15731574
}
1574-
return result;
15751575
}
15761576
}
15771577

@@ -1602,18 +1602,14 @@ private static class SaplingCheckBingdingSig implements Callable<Boolean> {
16021602

16031603
@Override
16041604
public Boolean call() throws ZksnarkException {
1605-
boolean result;
16061605
try {
1607-
result = JLibrustzcash.librustzcashSaplingFinalCheckNew(
1606+
return JLibrustzcash.librustzcashSaplingFinalCheckNew(
16081607
new LibrustzcashParam.FinalCheckNewParams(this.valueBalance, this.bindingSig,
16091608
this.signHash, this.spendCvs, this.spendCvLen,
16101609
this.receiveCvs, this.receiveCvLen));
1611-
} catch (ZksnarkException e) {
1612-
throw e;
16131610
} finally {
16141611
countDownLatch.countDown();
16151612
}
1616-
return result;
16171613
}
16181614
}
16191615
}
@@ -1637,6 +1633,10 @@ public Pair<Boolean, byte[]> execute(byte[] data) {
16371633
}
16381634
boolean result;
16391635
long ctx = JLibrustzcash.librustzcashSaplingVerificationCtxInit();
1636+
if (ctx == 0) {
1637+
logger.info("VerifyBurnProof: failed to init verification context");
1638+
return Pair.of(false, EMPTY_BYTE_ARRAY);
1639+
}
16401640
try {
16411641
byte[] nullifier = new byte[32];
16421642
byte[] anchor = new byte[32];

chainbase/src/main/java/org/tron/common/zksnark/JLibrustzcash.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
@Slf4j
3030
public class JLibrustzcash {
3131

32-
private static Librustzcash INSTANCE = LibrustzcashWrapper.getInstance();
32+
private static final Librustzcash INSTANCE = LibrustzcashWrapper.getInstance();
3333

3434
public static void librustzcashZip32XskMaster(Zip32XskMasterParams params) {
3535
INSTANCE.librustzcashZip32XskMaster(params.getData(), params.getSize(), params.getM_bytes());

0 commit comments

Comments
 (0)