-
Notifications
You must be signed in to change notification settings - Fork 1.7k
fix(crypto): bind burn cipher nonce to nullifier #6775
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: release_v4.8.2
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -30,6 +30,7 @@ | |
| import org.tron.core.zen.address.PaymentAddress; | ||
| import org.tron.core.zen.note.Note; | ||
| import org.tron.core.zen.note.NoteEncryption; | ||
| import org.tron.core.zen.note.NoteEncryption.Encryption; | ||
| import org.tron.core.zen.note.OutgoingPlaintext; | ||
| import org.tron.protos.contract.ShieldContract; | ||
| import org.tron.protos.contract.ShieldContract.ReceiveDescription; | ||
|
|
@@ -61,7 +62,9 @@ public class ShieldedTRC20ParametersBuilder { | |
| @Setter | ||
| private BigInteger transparentToAmount; | ||
| @Setter | ||
| private byte[] burnCiphertext = new byte[80]; | ||
| private byte[] ovk; | ||
| @Setter | ||
| private byte[] burnCiphertext = new byte[Encryption.BURN_CIPHER_RECORD_SIZE]; | ||
|
Comment on lines
+66
to
+67
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [SHOULD]
private byte[] burnCiphertext = new byte[Encryption.BURN_CIPHER_RECORD_SIZE];The default value is 96 zero bytes (legacy v1 zero-padding behavior). In the normal
Suggested fix: replace public void setBurnCiphertext(byte[] burnCiphertext) {
if (burnCiphertext == null
|| burnCiphertext.length != Encryption.BURN_CIPHER_RECORD_SIZE) {
throw new IllegalArgumentException("burnCiphertext must be 96 bytes");
}
this.burnCiphertext = burnCiphertext.clone();
} |
||
|
|
||
| public ShieldedTRC20ParametersBuilder() { | ||
|
|
||
|
|
@@ -207,6 +210,9 @@ private ReceiveDescriptionCapsule generateOutputProof(ReceiveDescriptionInfo out | |
|
|
||
| private void createSpendAuth(byte[] dataToBeSigned) throws ZksnarkException { | ||
| for (int i = 0; i < spends.size(); i++) { | ||
| if (spends.get(i).expsk == null) { | ||
| throw new ZksnarkException("missing expanded spending key for spend authorization"); | ||
| } | ||
| byte[] result = new byte[64]; | ||
| JLibrustzcash.librustzcashSaplingSpendSig( | ||
| new LibrustzcashParam.SpendSigParams(spends.get(i).expsk.getAsk(), | ||
|
|
@@ -292,6 +298,25 @@ public ShieldedTRC20Parameters build(boolean withAsk) throws ZksnarkException { | |
| SpendDescriptionInfo spend = spends.get(0); | ||
| spendDescription = generateSpendProof(spend, ctx).getInstance(); | ||
| builder.addSpendDescription(spendDescription); | ||
|
|
||
| if (ovk == null && spend.expsk != null) { | ||
| ovk = spend.expsk.getOvk(); | ||
| } | ||
| if (ovk == null) { | ||
| throw new ZksnarkException("missing ovk for burn encryption"); | ||
| } | ||
| byte[] nf = spendDescription.getNullifier().toByteArray(); | ||
| byte[] transparentToAddressTvm = normalizeTransparentToAddress(transparentToAddress); | ||
| byte[] addr21 = new byte[21]; | ||
| addr21[0] = Wallet.getAddressPreFixByte(); | ||
| System.arraycopy(transparentToAddressTvm, 0, addr21, 1, 20); | ||
| Optional<byte[]> cipherOpt = Encryption.encryptBurnMessageByOvk( | ||
| ovk, transparentToAmount, addr21, nf); | ||
| if (!cipherOpt.isPresent()) { | ||
| throw new ZksnarkException("encrypt burn message failed"); | ||
| } | ||
| burnCiphertext = cipherOpt.get(); | ||
|
|
||
| mergedBytes = ByteUtil.merge(shieldedTRC20Address, | ||
| encodeSpendDescriptionWithoutSpendAuthSig(spendDescription)); | ||
| if (receives.size() == 1) { | ||
|
|
@@ -302,7 +327,7 @@ public ShieldedTRC20Parameters build(boolean withAsk) throws ZksnarkException { | |
| encodeCencCout(receiveDescription)); | ||
| } | ||
| mergedBytes = ByteUtil | ||
| .merge(mergedBytes, transparentToAddress, ByteArray.fromLong(valueBalance)); | ||
| .merge(mergedBytes, transparentToAddressTvm, ByteArray.fromLong(valueBalance)); | ||
| value = transparentToAmount; | ||
| builder.setParameterType("burn"); | ||
| break; | ||
|
|
@@ -476,12 +501,10 @@ private String burnParamsToHexString(GrpcAPI.ShieldedTRC20Parameters burnParams, | |
| throw new IllegalArgumentException("the value must be positive"); | ||
| } | ||
|
|
||
| if (ArrayUtils.isEmpty(transparentToAddress)) { | ||
| throw new IllegalArgumentException("the transparent payTo address is null"); | ||
| } | ||
| byte[] transparentToAddressTvm = normalizeTransparentToAddress(transparentToAddress); | ||
|
|
||
| payTo[11] = Wallet.getAddressPreFixByte(); | ||
| System.arraycopy(transparentToAddress, 0, payTo, 12, 20); | ||
| System.arraycopy(transparentToAddressTvm, 0, payTo, 12, 20); | ||
| ShieldContract.SpendDescription spendDesc = burnParams.getSpendDescription(0); | ||
|
|
||
| byte[] spendAuthSign; | ||
|
|
@@ -492,7 +515,6 @@ private String burnParamsToHexString(GrpcAPI.ShieldedTRC20Parameters burnParams, | |
| } | ||
|
|
||
| byte[] mergedBytes; | ||
| byte[] zeros = new byte[16]; | ||
| mergedBytes = ByteUtil.merge( | ||
| spendDesc.getNullifier().toByteArray(), | ||
| spendDesc.getAnchor().toByteArray(), | ||
|
|
@@ -503,8 +525,7 @@ private String burnParamsToHexString(GrpcAPI.ShieldedTRC20Parameters burnParams, | |
| ByteUtil.bigIntegerToBytes(value, 32), | ||
| burnParams.getBindingSignature().toByteArray(), | ||
| payTo, | ||
| burnCiphertext, | ||
| zeros | ||
| burnCiphertext | ||
| ); | ||
|
|
||
| byte[] outputOffsetBytes; // 32 | ||
|
|
@@ -524,7 +545,7 @@ private String burnParamsToHexString(GrpcAPI.ShieldedTRC20Parameters burnParams, | |
| coffsetBytes = ByteUtil.longTo32Bytes(mergedBytes.length + 32 * 3 + 32L * 9); | ||
| countBytes = ByteUtil.longTo32Bytes(1L); | ||
| ReceiveDescription recvDesc = burnParams.getReceiveDescription(0); | ||
| zeros = new byte[12]; | ||
| byte[] zeros = new byte[12]; | ||
| mergedBytes = ByteUtil | ||
| .merge(mergedBytes, | ||
| outputOffsetBytes, | ||
|
|
@@ -542,6 +563,18 @@ private String burnParamsToHexString(GrpcAPI.ShieldedTRC20Parameters burnParams, | |
| return Hex.toHexString(mergedBytes); | ||
| } | ||
|
|
||
| private byte[] normalizeTransparentToAddress(byte[] transparentToAddress) { | ||
| if (transparentToAddress != null && transparentToAddress.length == 20) { | ||
| return transparentToAddress; | ||
| } | ||
| if (transparentToAddress != null && transparentToAddress.length == 21) { | ||
| byte[] transparentToAddressTvm = new byte[20]; | ||
| System.arraycopy(transparentToAddress, 1, transparentToAddressTvm, 0, 20); | ||
| return transparentToAddressTvm; | ||
| } | ||
| throw new IllegalArgumentException("invalid transparentToAddress for burn encryption"); | ||
| } | ||
|
|
||
| public void addSpend( | ||
| ExpandedSpendingKey expsk, | ||
| Note note, | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.