diff --git a/common-files/classes/public-inputs.mjs b/common-files/classes/public-inputs.mjs deleted file mode 100644 index b6dd5f7bb..000000000 --- a/common-files/classes/public-inputs.mjs +++ /dev/null @@ -1,25 +0,0 @@ -/* eslint import/no-extraneous-dependencies: "off" */ -/* ignore unused exports */ - -/** -Class to construct a public input hash (PIH). Unlike a commitment, the PIH -will vary quite a bit and so we use an array as the input -*/ -import gen from 'general-number'; -import sha256 from '../utils/crypto/sha256.mjs'; - -const { generalise } = gen; - -class PublicInputs { - publicInputs; - - hash; - - constructor(publicInputs) { - // some inputs may be general numbers and some strings. We convert all to string, process and generalise. - this.publicInputs = generalise(publicInputs.flat(Infinity)); - [, this.hash] = generalise(sha256(this.publicInputs).limbs(248, 2)); - } -} - -export default PublicInputs; diff --git a/common-files/classes/transaction.mjs b/common-files/classes/transaction.mjs index f52393d05..f5f31c8ff 100644 --- a/common-files/classes/transaction.mjs +++ b/common-files/classes/transaction.mjs @@ -40,7 +40,6 @@ class Transaction { historicRootBlockNumberL2, transactionType, tokenType, - publicInputs, // this must be an object of the PublicInputs calls tokenId, value, ercAddress, @@ -52,7 +51,6 @@ class Transaction { }) { if (proof === undefined) throw new Error('Proof cannot be undefined'); const flatProof = Object.values(proof).flat(Infinity); - if (publicInputs === undefined) throw new Error('PublicInputs cannot be undefined'); let commitments; let nullifiers; let compressedSecrets; @@ -74,7 +72,6 @@ class Transaction { historicRootBlockNumberL2: historicRootBlockNumberL2 || [0, 0], transactionType: transactionType || 0, tokenType: TOKEN_TYPES[tokenType] || 0, // tokenType does not matter for transfer - publicInputs: publicInputs.publicInputs ?? publicInputs, tokenId: tokenId || 0, value: value || 0, ercAddress: ercAddress || 0, diff --git a/common-files/utils/crypto/sha256.mjs b/common-files/utils/crypto/sha256.mjs index d0e8dd741..d6c97690f 100644 --- a/common-files/utils/crypto/sha256.mjs +++ b/common-files/utils/crypto/sha256.mjs @@ -43,4 +43,5 @@ const sha256 = generalValues => { return new GN(h); }; +// ignore unused exports export default sha256; diff --git a/nightfall-client/src/classes/index.mjs b/nightfall-client/src/classes/index.mjs index 8572a4741..521183974 100644 --- a/nightfall-client/src/classes/index.mjs +++ b/nightfall-client/src/classes/index.mjs @@ -1,8 +1,7 @@ -import PublicInputs from 'common-files/classes/public-inputs.mjs'; import Transaction from 'common-files/classes/transaction.mjs'; import Commitment from './commitment.mjs'; import Nullifier from './nullifier.mjs'; import Secrets from './secrets.mjs'; -export { PublicInputs, Transaction, Commitment, Nullifier, Secrets }; +export { Transaction, Commitment, Nullifier, Secrets }; diff --git a/nightfall-client/src/services/deposit.mjs b/nightfall-client/src/services/deposit.mjs index 9f5c2a0ad..9d4cba9f5 100644 --- a/nightfall-client/src/services/deposit.mjs +++ b/nightfall-client/src/services/deposit.mjs @@ -12,7 +12,7 @@ import gen from 'general-number'; import rand from 'common-files/utils/crypto/crypto-random.mjs'; import { getContractInstance } from 'common-files/utils/contract.mjs'; import logger from 'common-files/utils/logger.mjs'; -import { Commitment, PublicInputs, Transaction } from '../classes/index.mjs'; +import { Commitment, Transaction } from '../classes/index.mjs'; import { storeCommitment } from './commitment-storage.mjs'; import { compressPublicKey } from './keys.mjs'; @@ -41,11 +41,10 @@ async function deposit(items) { // we also need a salt to make the commitment unique and increase its entropy // eslint-disable-next-line salt = await rand(ZKP_KEY_LENGTH); - // next, let's compute the zkp commitment we're going to store and the hash of the public inputs (truncated to 248 bits) + // next, let's compute the zkp commitment we're going to store commitment = new Commitment({ ercAddress, tokenId, value, compressedPkd, salt }); } while (commitment.hash.bigInt > BN128_GROUP_ORDER); - const publicInputs = new PublicInputs([ercAddress, tokenId, value, commitment.hash]); logger.debug(`Hash of new commitment is ${commitment.hash.hex()}`); // now we can compute a Witness so that we can generate the proof const witness = [ @@ -77,7 +76,6 @@ async function deposit(items) { fee, transactionType: 0, tokenType: items.tokenType, - publicInputs, tokenId, value, ercAddress, diff --git a/nightfall-client/src/services/transfer.mjs b/nightfall-client/src/services/transfer.mjs index 9530319ae..8961acb8f 100644 --- a/nightfall-client/src/services/transfer.mjs +++ b/nightfall-client/src/services/transfer.mjs @@ -11,7 +11,7 @@ import gen from 'general-number'; import rand from 'common-files/utils/crypto/crypto-random.mjs'; import { getContractInstance } from 'common-files/utils/contract.mjs'; import logger from 'common-files/utils/logger.mjs'; -import { Secrets, Nullifier, Commitment, PublicInputs, Transaction } from '../classes/index.mjs'; +import { Secrets, Nullifier, Commitment, Transaction } from '../classes/index.mjs'; import { findUsableCommitmentsMutex, storeCommitment, @@ -124,14 +124,6 @@ async function transfer(transferParams) { roots, ); - // public inputs - const publicInputs = new PublicInputs([ - oldCommitments.map(commitment => commitment.preimage.ercAddress), - newCommitments.map(commitment => commitment.hash), - nullifiers.map(nullifier => generalise(nullifier.hash.hex(32, 31)).integer), - roots, - compressedSecrets.map(compressedSecret => compressedSecret.hex(32, 31)), - ]); // time for a quick sanity check. We expect the number of old commitments, // new commitments and nullifiers to be equal. if (nullifiers.length !== oldCommitments.length || nullifiers.length !== newCommitments.length) { @@ -206,7 +198,6 @@ async function transfer(transferParams) { fee, historicRootBlockNumberL2: blockNumberL2s, transactionType, - publicInputs, ercAddress: ZERO, // we don't want to expose the ERC address during a transfer commitments: newCommitments, nullifiers, diff --git a/nightfall-client/src/services/withdraw.mjs b/nightfall-client/src/services/withdraw.mjs index b2d1a0acb..48c213b34 100644 --- a/nightfall-client/src/services/withdraw.mjs +++ b/nightfall-client/src/services/withdraw.mjs @@ -10,7 +10,7 @@ import axios from 'axios'; import gen from 'general-number'; import { getContractInstance } from 'common-files/utils/contract.mjs'; import logger from 'common-files/utils/logger.mjs'; -import { Nullifier, PublicInputs, Transaction } from '../classes/index.mjs'; +import { Nullifier, Transaction } from '../classes/index.mjs'; import { findUsableCommitmentsMutex, markNullified, @@ -63,16 +63,7 @@ async function withdraw(withdrawParams) { ); logger.silly(`SiblingPath was: ${JSON.stringify(siblingPath)}`); - // public inputs - const { root, leafIndex, isOnChain } = commitmentTreeInfo; - const publicInputs = new PublicInputs([ - oldCommitment.preimage.ercAddress, - oldCommitment.preimage.tokenId, - oldCommitment.preimage.value, - generalise(nullifier.hash.hex(32, 31)).integer, - recipientAddress, - root, - ]); + const { leafIndex, isOnChain } = commitmentTreeInfo; // now we have everything we need to create a Witness and compute a proof const witness = [ @@ -109,7 +100,6 @@ async function withdraw(withdrawParams) { historicRootBlockNumberL2: [isOnChain, 0], transactionType: 3, tokenType: items.tokenType, - publicInputs, tokenId, value, ercAddress, diff --git a/nightfall-optimist/src/classes/index.mjs b/nightfall-optimist/src/classes/index.mjs index 16379c579..438ab93a0 100644 --- a/nightfall-optimist/src/classes/index.mjs +++ b/nightfall-optimist/src/classes/index.mjs @@ -1,9 +1,8 @@ import Proof from 'common-files/classes/proof.mjs'; -import PublicInputs from 'common-files/classes/public-inputs.mjs'; import Transaction from 'common-files/classes/transaction.mjs'; import BlockError from './block-error.mjs'; import TransactionError from './transaction-error.mjs'; import VerificationKey from './verification-key.mjs'; -export { Proof, PublicInputs, Transaction, BlockError, TransactionError, VerificationKey }; +export { Proof, Transaction, BlockError, TransactionError, VerificationKey }; diff --git a/nightfall-optimist/src/services/transaction-checker.mjs b/nightfall-optimist/src/services/transaction-checker.mjs index 410a6cd8f..ee74a2cd6 100644 --- a/nightfall-optimist/src/services/transaction-checker.mjs +++ b/nightfall-optimist/src/services/transaction-checker.mjs @@ -4,18 +4,11 @@ Here are the things that could be wrong with a transaction: - the proof doesn't verify - the transaction hash doesn't match with the preimage - the transaction type is inconsistent with the fields populated -- the public inputs hash is correct */ import config from 'config'; import gen from 'general-number'; import logger from 'common-files/utils/logger.mjs'; -import { - Transaction, - VerificationKey, - Proof, - TransactionError, - PublicInputs, -} from '../classes/index.mjs'; +import { Transaction, VerificationKey, Proof, TransactionError } from '../classes/index.mjs'; import { waitForContract } from '../event-handlers/subscribe.mjs'; import { getBlockByBlockNumberL2 } from './database.mjs'; import verify from './verify.mjs'; @@ -164,46 +157,54 @@ async function verifyProof(transaction) { switch (Number(transaction.transactionType)) { case 0: // deposit transaction - inputs = new PublicInputs([ - transaction.ercAddress, - transaction.tokenId, - transaction.value, - transaction.commitments[0], // not truncating here as we already ensured hash < group order - ]).publicInputs; + inputs = generalise( + [ + transaction.ercAddress, + transaction.tokenId, + transaction.value, + transaction.commitments[0], // not truncating here as we already ensured hash < group order + ].flat(Infinity), + ); break; case 1: // single transfer transaction - inputs = new PublicInputs([ - // transaction.ercAddress, - transaction.commitments[0], // not truncating here as we already ensured hash < group order - generalise(transaction.nullifiers[0]).hex(32, 31), - historicRootFirst.root, - ...transaction.compressedSecrets.map(compressedSecret => - generalise(compressedSecret).hex(32, 31), - ), - ]).publicInputs; + inputs = generalise( + [ + // transaction.ercAddress, + transaction.commitments[0], // not truncating here as we already ensured hash < group order + generalise(transaction.nullifiers[0]).hex(32, 31), + historicRootFirst.root, + ...transaction.compressedSecrets.map(compressedSecret => + generalise(compressedSecret).hex(32, 31), + ), + ].flat(Infinity), + ); break; case 2: // double transfer transaction - inputs = new PublicInputs([ - // transaction.ercAddress, // this is correct; ercAddress appears twice - // transaction.ercAddress, // in a double-transfer public input hash - transaction.commitments, // not truncating here as we already ensured hash < group order - transaction.nullifiers.map(nullifier => generalise(nullifier).hex(32, 31)), - historicRootFirst.root, - historicRootSecond.root, - ...transaction.compressedSecrets.map(compressedSecret => - generalise(compressedSecret).hex(32, 31), - ), - ]).publicInputs; + inputs = generalise( + [ + // transaction.ercAddress, // this is correct; ercAddress appears twice + // transaction.ercAddress, // in a double-transfer public input hash + transaction.commitments, // not truncating here as we already ensured hash < group order + transaction.nullifiers.map(nullifier => generalise(nullifier).hex(32, 31)), + historicRootFirst.root, + historicRootSecond.root, + ...transaction.compressedSecrets.map(compressedSecret => + generalise(compressedSecret).hex(32, 31), + ), + ].flat(Infinity), + ); break; case 3: // withdraw transaction - inputs = new PublicInputs([ - transaction.ercAddress, - transaction.tokenId, - transaction.value, - generalise(transaction.nullifiers[0]).hex(32, 31), - transaction.recipientAddress, - historicRootFirst.root, - ]).publicInputs; + inputs = generalise( + [ + transaction.ercAddress, + transaction.tokenId, + transaction.value, + generalise(transaction.nullifiers[0]).hex(32, 31), + transaction.recipientAddress, + historicRootFirst.root, + ].flat(Infinity), + ); break; default: throw new TransactionError('Unknown transaction type', 2);