diff --git a/.circleci/config.yml b/.circleci/config.yml index d20ce0863f5..e96dd4057ab 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -989,8 +989,8 @@ jobs: - *setup_env - run: name: "Test" - command: ./scripts/cond_run_script canary-build $JOB_NAME ./scripts/run_tests_local uniswap_trade_on_l1_from_l2.test.ts canary-build ./scripts/docker-compose-e2e-sandbox.yml - working_directory: yarn-project/end-to-end + command: ./scripts/cond_run_script canary-build $JOB_NAME ./scripts/run_tests uniswap_trade_on_l1_from_l2.test.ts canary-build ./scripts/docker-compose-e2e-sandbox.yml + working_directory: yarn-project/canary build-docs: machine: diff --git a/circuits/cpp/barretenberg/cpp/src/barretenberg/common/serialize.hpp b/circuits/cpp/barretenberg/cpp/src/barretenberg/common/serialize.hpp index 16d2c66e803..6452dcb7a4a 100644 --- a/circuits/cpp/barretenberg/cpp/src/barretenberg/common/serialize.hpp +++ b/circuits/cpp/barretenberg/cpp/src/barretenberg/common/serialize.hpp @@ -51,8 +51,7 @@ __extension__ using uint128_t = unsigned __int128; // NOLINTBEGIN(cppcoreguidelines-pro-type-reinterpret-cast, cert-dcl58-cpp) // clang-format on -template -concept IntegralOrEnum = std::integral || std::is_enum_v; +template concept IntegralOrEnum = std::integral || std::is_enum_v; namespace serialize { // Forward declare derived msgpack methods diff --git a/circuits/cpp/src/aztec3/circuits/abis/c_bind.cpp b/circuits/cpp/src/aztec3/circuits/abis/c_bind.cpp index 0b371c3acbd..15d5156dec5 100644 --- a/circuits/cpp/src/aztec3/circuits/abis/c_bind.cpp +++ b/circuits/cpp/src/aztec3/circuits/abis/c_bind.cpp @@ -185,7 +185,7 @@ WASM_EXPORT void abis__hash_vk(uint8_t const* vk_data_buf, uint8_t* output) * @brief Generates a function tree leaf from its preimage. * This is a WASM-export that can be called from Typescript. * - * @details given a `uint8_t const*` buffer representing a function leaf's prieimage, + * @details given a `uint8_t const*` buffer representing a function leaf's preimage, * construct a FunctionLeafPreimage instance, hash, and return the serialized results * in the `output` buffer. * diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/common.cpp b/circuits/cpp/src/aztec3/circuits/kernel/private/common.cpp index 7e49a3567c0..0492e789cf3 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/common.cpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/common.cpp @@ -140,7 +140,7 @@ void common_update_end_values(DummyBuilder& builder, const auto& storage_contract_address = private_call_public_inputs.call_context.storage_contract_address; - // Transient read requests and witnessess are accumulated in public_inputs.end + // Transient read requests and witnesses are accumulated in public_inputs.end // We silo the read requests (domain separation per contract address) { for (size_t i = 0; i < read_requests.size(); ++i) { @@ -193,10 +193,11 @@ void common_update_end_values(DummyBuilder& builder, std::array siloed_nullified_commitments{}; for (size_t i = 0; i < MAX_NEW_NULLIFIERS_PER_CALL; ++i) { siloed_nullified_commitments[i] = - nullified_commitments[i] == fr(0) ? fr(0) // don't silo when empty - : nullified_commitments[i] == fr(EMPTY_NULLIFIED_COMMITMENT) - ? fr(EMPTY_NULLIFIED_COMMITMENT) // don't silo when empty - : silo_commitment(storage_contract_address, nullified_commitments[i]); + nullified_commitments[i] == fr(0) + ? fr(0) // don't silo when empty + : nullified_commitments[i] == fr(EMPTY_NULLIFIED_COMMITMENT) + ? fr(EMPTY_NULLIFIED_COMMITMENT) // don't silo when empty + : silo_commitment(storage_contract_address, nullified_commitments[i]); } push_array_to_array( diff --git a/circuits/cpp/src/aztec3/circuits/rollup/base/.test.cpp b/circuits/cpp/src/aztec3/circuits/rollup/base/.test.cpp index 3e34dcb62c6..abd6dba76b8 100644 --- a/circuits/cpp/src/aztec3/circuits/rollup/base/.test.cpp +++ b/circuits/cpp/src/aztec3/circuits/rollup/base/.test.cpp @@ -475,8 +475,8 @@ TEST_F(base_rollup_tests, native_nullifier_tree_regression) DummyCircuitBuilder builder = DummyCircuitBuilder("base_rollup_tests__native_nullifier_tree_regression"); // This test runs after some data has already been inserted into the tree - // This test will pre-populate the tree with 6 * KERNEL_NEW_NULLILFIERS_LENGTH values (0 item + 6 * - // KERNEL_NEW_NULLILFIERS_LENGTH -1 more) simulating that a rollup inserting two random values has already + // This test will pre-populate the tree with 6 * KERNEL_NEW_NULLIFIERS_LENGTH values (0 item + 6 * + // KERNEL_NEW_NULLIFIERS_LENGTH -1 more) simulating that a rollup inserting two random values has already // succeeded. Note that this corresponds to 3 (1 already initialized and 2 new ones) base rollups. This rollup then // adds two further random values that will end up having their low nullifiers point at each other std::vector initial_values(6 * MAX_NEW_NULLIFIERS_PER_TX - 1, 0); diff --git a/yarn-project/acir-simulator/src/client/client_execution_context.ts b/yarn-project/acir-simulator/src/client/client_execution_context.ts index 49b75afaa13..1f2810a2231 100644 --- a/yarn-project/acir-simulator/src/client/client_execution_context.ts +++ b/yarn-project/acir-simulator/src/client/client_execution_context.ts @@ -78,12 +78,14 @@ export class ClientTxExecutionContext { * @param contractAddress - The contract address. * @param ownerX - The x coordinate of the owner's public key. * @param ownerY - The y coordinate of the owner's public key. - * @returns The secret key of the owner. + * @returns The secret key of the owner as a pair of ACVM fields. */ public async getSecretKey(contractAddress: AztecAddress, ownerX: ACVMField, ownerY: ACVMField) { - return toACVMField( - (await this.db.getSecretKey(contractAddress, new Point(fromACVMField(ownerX), fromACVMField(ownerY)))).value, + const secretKey = await this.db.getSecretKey( + contractAddress, + new Point(fromACVMField(ownerX), fromACVMField(ownerY)), ); + return [toACVMField(secretKey.high), toACVMField(secretKey.low)]; } /** diff --git a/yarn-project/acir-simulator/src/client/db_oracle.ts b/yarn-project/acir-simulator/src/client/db_oracle.ts index b77eff0e0da..5f8e68846a1 100644 --- a/yarn-project/acir-simulator/src/client/db_oracle.ts +++ b/yarn-project/acir-simulator/src/client/db_oracle.ts @@ -1,4 +1,4 @@ -import { CompleteAddress, HistoricBlockData, PrivateKey, PublicKey } from '@aztec/circuits.js'; +import { CompleteAddress, GrumpkinPrivateKey, HistoricBlockData, PublicKey } from '@aztec/circuits.js'; import { FunctionAbi, FunctionDebugMetadata, FunctionSelector } from '@aztec/foundation/abi'; import { AztecAddress } from '@aztec/foundation/aztec-address'; import { EthAddress } from '@aztec/foundation/eth-address'; @@ -102,10 +102,10 @@ export interface DBOracle extends CommitmentsDB { * * @param contractAddress - The contract address. Ignored here. But we might want to return different keys for different contracts. * @param pubKey - The public key of an account. - * @returns A Promise that resolves to the secret key as a Buffer. + * @returns A Promise that resolves to the secret key. * @throws An Error if the input address does not match the public key address of the key pair. */ - getSecretKey(contractAddress: AztecAddress, pubKey: PublicKey): Promise; + getSecretKey(contractAddress: AztecAddress, pubKey: PublicKey): Promise; /** * Retrieves a set of notes stored in the database for a given contract address and storage slot. diff --git a/yarn-project/acir-simulator/src/client/private_execution.test.ts b/yarn-project/acir-simulator/src/client/private_execution.test.ts index 0a4202791b1..7f0dd6d8cba 100644 --- a/yarn-project/acir-simulator/src/client/private_execution.test.ts +++ b/yarn-project/acir-simulator/src/client/private_execution.test.ts @@ -9,7 +9,6 @@ import { L1_TO_L2_MSG_TREE_HEIGHT, MAX_NEW_COMMITMENTS_PER_CALL, PRIVATE_DATA_TREE_HEIGHT, - PrivateKey, PublicCallRequest, TxContext, } from '@aztec/circuits.js'; @@ -28,7 +27,7 @@ import { asyncMap } from '@aztec/foundation/async-map'; import { AztecAddress } from '@aztec/foundation/aztec-address'; import { toBufferBE } from '@aztec/foundation/bigint-buffer'; import { EthAddress } from '@aztec/foundation/eth-address'; -import { Fr } from '@aztec/foundation/fields'; +import { Fr, GrumpkinScalar } from '@aztec/foundation/fields'; import { DebugLogger, createDebugLogger } from '@aztec/foundation/log'; import { AppendOnlyTree, Pedersen, StandardTree, newTree } from '@aztec/merkle-tree'; import { @@ -66,7 +65,7 @@ describe('Private Execution test suite', () => { let logger: DebugLogger; const defaultContractAddress = AztecAddress.random(); - const ownerPk = PrivateKey.fromString('5e30a2f886b4b6a11aea03bf4910fbd5b24e61aa27ea4d05c393b3ab592a8d33'); + const ownerPk = GrumpkinScalar.fromString('2dcc5485a58316776299be08c78fa3788a1a7961ae30dc747fb1be17692a8d32'); const treeHeights: { [name: string]: number } = { privateData: PRIVATE_DATA_TREE_HEIGHT, @@ -168,7 +167,7 @@ describe('Private Execution test suite', () => { describe('private token airdrop contract', () => { const contractAddress = defaultContractAddress; - const recipientPk = PrivateKey.fromString('0c9ed344548e8f9ba8aa3c9f8651eaa2853130f6c1e9c050ccf198f7ea18a7ec'); + const recipientPk = GrumpkinScalar.fromString('0c9ed344548e8f9ba8aa3c9f8651eaa2853130f6c1e9c050ccf198f7ea18a7ec'); const mockFirstNullifier = new Fr(1111); let owner: AztecAddress; let recipient: AztecAddress; @@ -233,7 +232,11 @@ describe('Private Execution test suite', () => { const siloedNoteHash = siloCommitment(circuitsWasm, contractAddress, innerNoteHash); const uniqueSiloedNoteHash = computeUniqueCommitment(circuitsWasm, note.nonce, siloedNoteHash); const innerNullifier = Fr.fromBuffer( - pedersenPlookupCommitInputs(circuitsWasm, [uniqueSiloedNoteHash.toBuffer(), ownerPk.value]), + pedersenPlookupCommitInputs(circuitsWasm, [ + uniqueSiloedNoteHash.toBuffer(), + ownerPk.high.toBuffer(), + ownerPk.low.toBuffer(), + ]), ); const result = await acirSimulator.computeNoteHashAndNullifier( @@ -400,7 +403,7 @@ describe('Private Execution test suite', () => { describe('private token contract', () => { const contractAddress = defaultContractAddress; - const recipientPk = PrivateKey.fromString('0c9ed344548e8f9ba8aa3c9f8651eaa2853130f6c1e9c050ccf198f7ea18a7ec'); + const recipientPk = GrumpkinScalar.fromString('0c9ed344548e8f9ba8aa3c9f8651eaa2853130f6c1e9c050ccf198f7ea18a7ec'); const mockFirstNullifier = new Fr(1111); let owner: AztecAddress; let recipient: AztecAddress; @@ -465,7 +468,11 @@ describe('Private Execution test suite', () => { const siloedNoteHash = siloCommitment(circuitsWasm, contractAddress, innerNoteHash); const uniqueSiloedNoteHash = computeUniqueCommitment(circuitsWasm, note.nonce, siloedNoteHash); const innerNullifier = Fr.fromBuffer( - pedersenPlookupCommitInputs(circuitsWasm, [uniqueSiloedNoteHash.toBuffer(), ownerPk.value]), + pedersenPlookupCommitInputs(circuitsWasm, [ + uniqueSiloedNoteHash.toBuffer(), + ownerPk.high.toBuffer(), + ownerPk.low.toBuffer(), + ]), ); const result = await acirSimulator.computeNoteHashAndNullifier( @@ -680,7 +687,7 @@ describe('Private Execution test suite', () => { describe('consuming messages', () => { const contractAddress = defaultContractAddress; - const recipientPk = PrivateKey.fromString('0c9ed344548e8f9ba8aa3c9f8651eaa2853130f6c1e9c050ccf198f7ea18a7ec'); + const recipientPk = GrumpkinScalar.fromString('0c9ed344548e8f9ba8aa3c9f8651eaa2853130f6c1e9c050ccf198f7ea18a7ec'); let recipient: AztecAddress; diff --git a/yarn-project/acir-simulator/src/client/unconstrained_execution.test.ts b/yarn-project/acir-simulator/src/client/unconstrained_execution.test.ts index 1e4dbf69421..fb77873200d 100644 --- a/yarn-project/acir-simulator/src/client/unconstrained_execution.test.ts +++ b/yarn-project/acir-simulator/src/client/unconstrained_execution.test.ts @@ -1,8 +1,8 @@ -import { CompleteAddress, FunctionData, HistoricBlockData, PrivateKey } from '@aztec/circuits.js'; +import { CompleteAddress, FunctionData, HistoricBlockData } from '@aztec/circuits.js'; import { FunctionSelector, encodeArguments } from '@aztec/foundation/abi'; import { AztecAddress } from '@aztec/foundation/aztec-address'; import { EthAddress } from '@aztec/foundation/eth-address'; -import { Fr } from '@aztec/foundation/fields'; +import { Fr, GrumpkinScalar } from '@aztec/foundation/fields'; import { PrivateTokenContractAbi } from '@aztec/noir-contracts/artifacts'; import { FunctionCall } from '@aztec/types'; @@ -21,7 +21,7 @@ describe('Unconstrained Execution test suite', () => { }); describe('private token contract', () => { - const ownerPk = PrivateKey.fromString('5e30a2f886b4b6a11aea03bf4910fbd5b24e61aa27ea4d05c393b3ab592a8d33'); + const ownerPk = GrumpkinScalar.fromString('2dcc5485a58316776299be08c78fa3788a1a7961ae30dc747fb1be17692a8d32'); let owner: AztecAddress; diff --git a/yarn-project/acir-simulator/src/utils.ts b/yarn-project/acir-simulator/src/utils.ts index 05462bf383b..fa30e578657 100644 --- a/yarn-project/acir-simulator/src/utils.ts +++ b/yarn-project/acir-simulator/src/utils.ts @@ -1,4 +1,4 @@ -import { CircuitsWasm, PrivateKey } from '@aztec/circuits.js'; +import { CircuitsWasm, GrumpkinPrivateKey } from '@aztec/circuits.js'; import { Grumpkin, pedersenPlookupCommitInputs } from '@aztec/circuits.js/barretenberg'; import { Fr } from '@aztec/foundation/fields'; @@ -37,7 +37,7 @@ export function computeSlotForMapping(mappingSlot: Fr, owner: NoirPoint | Fr, bb * @param grumpkin - The grumpkin instance. * @returns The public key. */ -export function toPublicKey(privateKey: PrivateKey, grumpkin: Grumpkin): NoirPoint { +export function toPublicKey(privateKey: GrumpkinPrivateKey, grumpkin: Grumpkin): NoirPoint { const point = grumpkin.mul(Grumpkin.generator, privateKey); return { x: point.x.value, diff --git a/yarn-project/aztec-cli/src/index.ts b/yarn-project/aztec-cli/src/index.ts index 4e42858bf9d..a2fb1880758 100644 --- a/yarn-project/aztec-cli/src/index.ts +++ b/yarn-project/aztec-cli/src/index.ts @@ -3,6 +3,7 @@ import { Contract, ContractDeployer, Fr, + GrumpkinScalar, Point, generatePublicKey, getAccountWallets, @@ -15,7 +16,7 @@ import { DebugLogger, LogFn } from '@aztec/foundation/log'; import { fileURLToPath } from '@aztec/foundation/url'; import { compileContract } from '@aztec/noir-compiler/cli'; import { SchnorrAccountContractAbi } from '@aztec/noir-contracts/artifacts'; -import { CompleteAddress, ContractData, L2BlockL2Logs, PrivateKey, TxHash } from '@aztec/types'; +import { CompleteAddress, ContractData, L2BlockL2Logs, TxHash } from '@aztec/types'; import { Command } from 'commander'; import { readFileSync } from 'fs'; @@ -94,7 +95,10 @@ export function getProgram(log: LogFn, debugLogger: DebugLogger): Command { program .command('generate-private-key') - .description('Generates a 32-byte private key.') + .summary('Generates an encryption private key.') + .description( + 'Generates a private key which fits into the scalar field used by Grumpkin curve, can be used as an encryption private key.', + ) .option( '-m, --mnemonic', 'An optional mnemonic string used for the private key generation. If not provided, random private key will be generated.', @@ -104,11 +108,11 @@ export function getProgram(log: LogFn, debugLogger: DebugLogger): Command { let publicKey; if (options.mnemonic) { const acc = mnemonicToAccount(options.mnemonic); - const key = Buffer.from(acc.getHdKey().privateKey!); - privKey = key.toString('hex'); - publicKey = await generatePublicKey(new PrivateKey(key)); + // TODO(#2052): This reduction is not secure enough. TACKLE THIS ISSUE BEFORE MAINNET. + const key = GrumpkinScalar.fromBufferWithReduction(Buffer.from(acc.getHdKey().privateKey!)); + publicKey = await generatePublicKey(key); } else { - const key = PrivateKey.random(); + const key = GrumpkinScalar.random(); privKey = key.toString(); publicKey = await generatePublicKey(key); } @@ -130,8 +134,8 @@ export function getProgram(log: LogFn, debugLogger: DebugLogger): Command { .action(async options => { const client = await createCompatibleClient(options.rpcUrl, debugLogger); const privateKey = options.privateKey - ? PrivateKey.fromString(stripLeadingHex(options.privateKey)) - : PrivateKey.random(); + ? GrumpkinScalar.fromString(stripLeadingHex(options.privateKey)) + : GrumpkinScalar.random(); const account = getSchnorrAccount(client, privateKey, privateKey, accountCreationSalt); const wallet = await account.waitDeploy(); @@ -380,7 +384,7 @@ export function getProgram(log: LogFn, debugLogger: DebugLogger): Command { ); } - const privateKey = PrivateKey.fromString(stripLeadingHex(options.privateKey)); + const privateKey = GrumpkinScalar.fromString(stripLeadingHex(options.privateKey)); const client = await createCompatibleClient(options.rpcUrl, debugLogger); const wallet = await getAccountWallets( diff --git a/yarn-project/aztec-rpc/src/aztec_rpc_http/aztec_rpc_http_server.ts b/yarn-project/aztec-rpc/src/aztec_rpc_http/aztec_rpc_http_server.ts index a5d3d296d5b..0b326f0a538 100644 --- a/yarn-project/aztec-rpc/src/aztec_rpc_http/aztec_rpc_http_server.ts +++ b/yarn-project/aztec-rpc/src/aztec_rpc_http/aztec_rpc_http_server.ts @@ -1,5 +1,5 @@ import { AztecAddress } from '@aztec/foundation/aztec-address'; -import { Fr, Point } from '@aztec/foundation/fields'; +import { Fr, GrumpkinScalar, Point } from '@aztec/foundation/fields'; import { JsonRpcServer } from '@aztec/foundation/json-rpc/server'; import { AztecRPC, @@ -8,7 +8,6 @@ import { ExtendedContractData, L2BlockL2Logs, NotePreimage, - PrivateKey, Tx, TxExecutionRequest, TxHash, @@ -37,8 +36,8 @@ export function getHttpRpcServer(aztecRpcServer: AztecRPC): JsonRpcServer { TxHash, EthAddress, Point, - PrivateKey, Fr, + GrumpkinScalar, NotePreimage, }, { Tx, TxReceipt, L2BlockL2Logs }, diff --git a/yarn-project/aztec-rpc/src/aztec_rpc_server/aztec_rpc_server.ts b/yarn-project/aztec-rpc/src/aztec_rpc_server/aztec_rpc_server.ts index 18c3b732a3e..9c21be42715 100644 --- a/yarn-project/aztec-rpc/src/aztec_rpc_server/aztec_rpc_server.ts +++ b/yarn-project/aztec-rpc/src/aztec_rpc_server/aztec_rpc_server.ts @@ -10,10 +10,10 @@ import { CompleteAddress, EthAddress, FunctionData, + GrumpkinPrivateKey, KernelCircuitPublicInputsFinal, MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, PartialAddress, - PrivateKey, PublicCallRequest, } from '@aztec/circuits.js'; import { encodeArguments } from '@aztec/foundation/abi'; @@ -104,7 +104,7 @@ export class AztecRPCServer implements AztecRPC { this.log.info('Stopped'); } - public async registerAccount(privKey: PrivateKey, partialAddress: PartialAddress) { + public async registerAccount(privKey: GrumpkinPrivateKey, partialAddress: PartialAddress) { const completeAddress = await CompleteAddress.fromPrivateKeyAndPartialAddress(privKey, partialAddress); const wasAdded = await this.db.addCompleteAddress(completeAddress); if (wasAdded) { diff --git a/yarn-project/aztec-rpc/src/kernel_prover/kernel_prover.ts b/yarn-project/aztec-rpc/src/kernel_prover/kernel_prover.ts index d85bf17a0df..48608944a68 100644 --- a/yarn-project/aztec-rpc/src/kernel_prover/kernel_prover.ts +++ b/yarn-project/aztec-rpc/src/kernel_prover/kernel_prover.ts @@ -2,6 +2,7 @@ import { ExecutionResult, NewNoteData } from '@aztec/acir-simulator'; import { AztecAddress, CONTRACT_TREE_HEIGHT, + EMPTY_NULLIFIED_COMMITMENT, Fr, MAX_NEW_COMMITMENTS_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, @@ -23,7 +24,6 @@ import { makeEmptyProof, makeTuple, } from '@aztec/circuits.js'; -import { EMPTY_NULLIFIED_COMMITMENT } from '@aztec/circuits.js'; import { Tuple, assertLength } from '@aztec/foundation/serialize'; import { KernelProofCreator, ProofCreator, ProofOutput, ProofOutputFinal } from './proof_creator.js'; diff --git a/yarn-project/aztec-rpc/src/simulator_oracle/index.ts b/yarn-project/aztec-rpc/src/simulator_oracle/index.ts index 08f613978e0..6ff952648a3 100644 --- a/yarn-project/aztec-rpc/src/simulator_oracle/index.ts +++ b/yarn-project/aztec-rpc/src/simulator_oracle/index.ts @@ -11,8 +11,8 @@ import { EthAddress, Fr, FunctionSelector, + GrumpkinPrivateKey, HistoricBlockData, - PrivateKey, PublicKey, } from '@aztec/circuits.js'; import { siloCommitment } from '@aztec/circuits.js/abis'; @@ -33,7 +33,7 @@ export class SimulatorOracle implements DBOracle { private dataTreeProvider: DataCommitmentProvider, ) {} - getSecretKey(_contractAddress: AztecAddress, pubKey: PublicKey): Promise { + getSecretKey(_contractAddress: AztecAddress, pubKey: PublicKey): Promise { return this.keyStore.getAccountPrivateKey(pubKey); } diff --git a/yarn-project/aztec-rpc/src/synchroniser/synchroniser.test.ts b/yarn-project/aztec-rpc/src/synchroniser/synchroniser.test.ts index d3e46f8d444..631b294f3b3 100644 --- a/yarn-project/aztec-rpc/src/synchroniser/synchroniser.test.ts +++ b/yarn-project/aztec-rpc/src/synchroniser/synchroniser.test.ts @@ -1,4 +1,4 @@ -import { CompleteAddress, Fr, HistoricBlockData, PrivateKey } from '@aztec/circuits.js'; +import { CompleteAddress, Fr, GrumpkinScalar, HistoricBlockData } from '@aztec/circuits.js'; import { Grumpkin } from '@aztec/circuits.js/barretenberg'; import { TestKeyStore } from '@aztec/key-store'; import { AztecNode, L2Block, MerkleTreeId } from '@aztec/types'; @@ -103,7 +103,7 @@ describe('Synchroniser', () => { // Manually adding account to database so that we can call synchroniser.isAccountStateSynchronised const keyStore = new TestKeyStore(await Grumpkin.new()); - const privateKey = PrivateKey.random(); + const privateKey = GrumpkinScalar.random(); keyStore.addAccount(privateKey); const completeAddress = await CompleteAddress.fromPrivateKeyAndPartialAddress(privateKey, Fr.random()); await database.addCompleteAddress(completeAddress); diff --git a/yarn-project/aztec-sandbox/src/examples/private_token_contract.ts b/yarn-project/aztec-sandbox/src/examples/private_token_contract.ts index 91e1dae1a42..6a5dd3e0fce 100644 --- a/yarn-project/aztec-sandbox/src/examples/private_token_contract.ts +++ b/yarn-project/aztec-sandbox/src/examples/private_token_contract.ts @@ -1,11 +1,19 @@ -import { AztecAddress, Contract, Fr, PrivateKey, Wallet, createAccounts, createAztecRpcClient } from '@aztec/aztec.js'; +import { + AztecAddress, + Contract, + Fr, + GrumpkinScalar, + Wallet, + createAccounts, + createAztecRpcClient, +} from '@aztec/aztec.js'; import { createDebugLogger } from '@aztec/foundation/log'; import { SchnorrSingleKeyAccountContractAbi } from '@aztec/noir-contracts/artifacts'; import { PrivateTokenContract } from '@aztec/noir-contracts/types'; const logger = createDebugLogger('aztec:http-rpc-client'); -export const privateKey = PrivateKey.fromString('ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80'); +export const privateKey = GrumpkinScalar.fromString('ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80'); const url = 'http://localhost:8080'; diff --git a/yarn-project/aztec-sandbox/src/examples/uniswap_trade_on_l1_from_l2.ts b/yarn-project/aztec-sandbox/src/examples/uniswap_trade_on_l1_from_l2.ts index 62cefe4ed74..ea2d7b73e18 100644 --- a/yarn-project/aztec-sandbox/src/examples/uniswap_trade_on_l1_from_l2.ts +++ b/yarn-project/aztec-sandbox/src/examples/uniswap_trade_on_l1_from_l2.ts @@ -8,7 +8,7 @@ import { createAztecRpcClient, getL1ContractAddresses, } from '@aztec/aztec.js'; -import { PrivateKey } from '@aztec/circuits.js'; +import { GrumpkinScalar } from '@aztec/circuits.js'; import { createDebugLogger } from '@aztec/foundation/log'; import { UniswapPortalAbi, UniswapPortalBytecode } from '@aztec/l1-artifacts'; import { SchnorrSingleKeyAccountContractAbi } from '@aztec/noir-contracts/artifacts'; @@ -37,7 +37,7 @@ const aztecRpcUrl = 'http://localhost:8080'; const ethRpcUrl = 'http://localhost:8545'; const hdAccount = mnemonicToAccount(MNEMONIC); -const privateKey = new PrivateKey(Buffer.from(hdAccount.getHdKey().privateKey!)); +const privateKey = GrumpkinScalar.fromBuffer(Buffer.from(hdAccount.getHdKey().privateKey!)); const walletClient = createWalletClient({ account: hdAccount, diff --git a/yarn-project/aztec-sandbox/src/sandbox.ts b/yarn-project/aztec-sandbox/src/sandbox.ts index ff1f7c7bc21..8d25be5a200 100644 --- a/yarn-project/aztec-sandbox/src/sandbox.ts +++ b/yarn-project/aztec-sandbox/src/sandbox.ts @@ -1,7 +1,6 @@ #!/usr/bin/env -S node --no-warnings import { AztecNodeConfig, AztecNodeService, getConfigEnvVars } from '@aztec/aztec-node'; import { createAztecRPCServer, getConfigEnvVars as getRpcConfigEnvVars } from '@aztec/aztec-rpc'; -import { PrivateKey } from '@aztec/circuits.js'; import { deployL1Contracts } from '@aztec/ethereum'; import { createDebugLogger } from '@aztec/foundation/log'; import { retryUntil } from '@aztec/foundation/retry'; @@ -67,7 +66,7 @@ export async function createSandbox(config: Partial = {}) { const privKey = hdAccount.getHdKey().privateKey; const l1Contracts = await waitThenDeploy(aztecNodeConfig.rpcUrl, hdAccount); - aztecNodeConfig.publisherPrivateKey = new PrivateKey(Buffer.from(privKey!)); + aztecNodeConfig.publisherPrivateKey = `0x${Buffer.from(privKey!).toString('hex')}`; aztecNodeConfig.rollupContract = l1Contracts.rollupAddress; aztecNodeConfig.contractDeploymentEmitterContract = l1Contracts.contractDeploymentEmitterAddress; aztecNodeConfig.inboxContract = l1Contracts.inboxAddress; diff --git a/yarn-project/aztec.js/src/abis/ecdsa_account_contract.json b/yarn-project/aztec.js/src/abis/ecdsa_account_contract.json index b5b00bdf017..052ddb70908 100644 --- a/yarn-project/aztec.js/src/abis/ecdsa_account_contract.json +++ b/yarn-project/aztec.js/src/abis/ecdsa_account_contract.json @@ -48,7 +48,7 @@ } } ], - "bytecode": "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", + "bytecode": "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", "verificationKey": "0000000200000800000000740000000f00000003515f3109623eb3c25aa5b16a1a79fd558bac7a7ce62c4560a8c537c77ce80dd339128d1d37b6582ee9e6df9567efb64313471dfa18f520f9ce53161b50dbf7731bc5f900000003515f322bc4cce83a486a92c92fd59bd84e0f92595baa639fc2ed86b00ffa0dfded2a092a669a3bdb7a273a015eda494457cc7ed5236f26cee330c290d45a33b9daa94800000003515f332729426c008c085a81bd34d8ef12dd31e80130339ef99d50013a89e4558eee6d0fa4ffe2ee7b7b62eb92608b2251ac31396a718f9b34978888789042b790a30100000003515f342be6b6824a913eb7a57b03cb1ee7bfb4de02f2f65fe8a4e97baa7766ddb353a82a8a25c49dc63778cd9fe96173f12a2bc77f3682f4c4448f98f1df82c75234a100000003515f351f85760d6ab567465aadc2f180af9eae3800e6958fec96aef53fd8a7b195d7c000c6267a0dd5cfc22b3fe804f53e266069c0e36f51885baec1e7e67650c62e170000000c515f41524954484d455449430d9d0f8ece2aa12012fa21e6e5c859e97bd5704e5c122064a66051294bc5e04213f61f54a0ebdf6fee4d4a6ecf693478191de0c2899bcd8e86a636c8d3eff43400000003515f43224a99d02c86336737c8dd5b746c40d2be6aead8393889a76a18d664029096e90f7fe81adcc92a74350eada9622ac453f49ebac24a066a1f83b394df54dfa0130000000c515f46495845445f42415345060e8a013ed289c2f9fd7473b04f6594b138ddb4b4cf6b901622a14088f04b8d2c83ff74fce56e3d5573b99c7b26d85d5046ce0c6559506acb7a675e7713eb3a00000007515f4c4f4749430721a91cb8da4b917e054f72147e1760cfe0ef3d45090ac0f4961d84ec1996961a25e787b26bd8b50b1a99450f77a424a83513c2b33af268cd253b0587ff50c700000003515f4d05dbd8623b8652511e1eb38d38887a69eceb082f807514f09e127237c5213b401b9325b48c6c225968002318095f89d0ef9cf629b2b7f0172e03bc39aacf6ed800000007515f52414e474504b57a3805e41df328f5ca9aefa40fad5917391543b7b65c6476e60b8f72e9ad07c92f3b3e11c8feae96dedc4b14a6226ef3201244f37cfc1ee5b96781f48d2b000000075349474d415f3125001d1954a18571eaa007144c5a567bb0d2be4def08a8be918b8c05e3b27d312c59ed41e09e144eab5de77ca89a2fd783be702a47c951d3112e3de02ce6e47c000000075349474d415f3223994e6a23618e60fa01c449a7ab88378709197e186d48d604bfb6931ffb15ad11c5ec7a0700570f80088fd5198ab5d5c227f2ad2a455a6edeec024156bb7beb000000075349474d415f3300cda5845f23468a13275d18bddae27c6bb189cf9aa95b6a03a0cb6688c7e8d829639b45cf8607c525cc400b55ebf90205f2f378626dc3406cc59b2d1b474fba000000075349474d415f342d299e7928496ea2d37f10b43afd6a80c90a33b483090d18069ffa275eedb2fc2f82121e8de43dc036d99b478b6227ceef34248939987a19011f065d8b5cef5c0000000010000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f" }, { diff --git a/yarn-project/aztec.js/src/abis/schnorr_account_contract.json b/yarn-project/aztec.js/src/abis/schnorr_account_contract.json index 37508393ca7..b40cf7e175a 100644 --- a/yarn-project/aztec.js/src/abis/schnorr_account_contract.json +++ b/yarn-project/aztec.js/src/abis/schnorr_account_contract.json @@ -48,7 +48,7 @@ } } ], - "bytecode": "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", + "bytecode": "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", "verificationKey": "0000000200000800000000740000000f00000003515f3109623eb3c25aa5b16a1a79fd558bac7a7ce62c4560a8c537c77ce80dd339128d1d37b6582ee9e6df9567efb64313471dfa18f520f9ce53161b50dbf7731bc5f900000003515f322bc4cce83a486a92c92fd59bd84e0f92595baa639fc2ed86b00ffa0dfded2a092a669a3bdb7a273a015eda494457cc7ed5236f26cee330c290d45a33b9daa94800000003515f332729426c008c085a81bd34d8ef12dd31e80130339ef99d50013a89e4558eee6d0fa4ffe2ee7b7b62eb92608b2251ac31396a718f9b34978888789042b790a30100000003515f342be6b6824a913eb7a57b03cb1ee7bfb4de02f2f65fe8a4e97baa7766ddb353a82a8a25c49dc63778cd9fe96173f12a2bc77f3682f4c4448f98f1df82c75234a100000003515f351f85760d6ab567465aadc2f180af9eae3800e6958fec96aef53fd8a7b195d7c000c6267a0dd5cfc22b3fe804f53e266069c0e36f51885baec1e7e67650c62e170000000c515f41524954484d455449430d9d0f8ece2aa12012fa21e6e5c859e97bd5704e5c122064a66051294bc5e04213f61f54a0ebdf6fee4d4a6ecf693478191de0c2899bcd8e86a636c8d3eff43400000003515f43224a99d02c86336737c8dd5b746c40d2be6aead8393889a76a18d664029096e90f7fe81adcc92a74350eada9622ac453f49ebac24a066a1f83b394df54dfa0130000000c515f46495845445f42415345060e8a013ed289c2f9fd7473b04f6594b138ddb4b4cf6b901622a14088f04b8d2c83ff74fce56e3d5573b99c7b26d85d5046ce0c6559506acb7a675e7713eb3a00000007515f4c4f4749430721a91cb8da4b917e054f72147e1760cfe0ef3d45090ac0f4961d84ec1996961a25e787b26bd8b50b1a99450f77a424a83513c2b33af268cd253b0587ff50c700000003515f4d05dbd8623b8652511e1eb38d38887a69eceb082f807514f09e127237c5213b401b9325b48c6c225968002318095f89d0ef9cf629b2b7f0172e03bc39aacf6ed800000007515f52414e474504b57a3805e41df328f5ca9aefa40fad5917391543b7b65c6476e60b8f72e9ad07c92f3b3e11c8feae96dedc4b14a6226ef3201244f37cfc1ee5b96781f48d2b000000075349474d415f3125001d1954a18571eaa007144c5a567bb0d2be4def08a8be918b8c05e3b27d312c59ed41e09e144eab5de77ca89a2fd783be702a47c951d3112e3de02ce6e47c000000075349474d415f3223994e6a23618e60fa01c449a7ab88378709197e186d48d604bfb6931ffb15ad11c5ec7a0700570f80088fd5198ab5d5c227f2ad2a455a6edeec024156bb7beb000000075349474d415f3300cda5845f23468a13275d18bddae27c6bb189cf9aa95b6a03a0cb6688c7e8d829639b45cf8607c525cc400b55ebf90205f2f378626dc3406cc59b2d1b474fba000000075349474d415f342d299e7928496ea2d37f10b43afd6a80c90a33b483090d18069ffa275eedb2fc2f82121e8de43dc036d99b478b6227ceef34248939987a19011f065d8b5cef5c0000000010000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f" }, { diff --git a/yarn-project/aztec.js/src/account/account.ts b/yarn-project/aztec.js/src/account/account.ts index 698e1185aa1..f597c7d0a63 100644 --- a/yarn-project/aztec.js/src/account/account.ts +++ b/yarn-project/aztec.js/src/account/account.ts @@ -1,5 +1,5 @@ import { Fr, PublicKey, getContractDeploymentInfo } from '@aztec/circuits.js'; -import { AztecRPC, CompleteAddress, PrivateKey } from '@aztec/types'; +import { AztecRPC, CompleteAddress, GrumpkinPrivateKey } from '@aztec/types'; import { AccountWallet, ContractDeployer, DeployMethod, WaitOpts, generatePublicKey } from '../index.js'; import { DeployAccountSentTx } from './deploy_account_sent_tx.js'; @@ -19,7 +19,7 @@ export class Account { constructor( private rpc: AztecRPC, - private encryptionPrivateKey: PrivateKey, + private encryptionPrivateKey: GrumpkinPrivateKey, private accountContract: AccountContract, saltOrAddress?: Salt | CompleteAddress, ) { diff --git a/yarn-project/aztec.js/src/account/contract/auth_witness_account_contract.ts b/yarn-project/aztec.js/src/account/contract/auth_witness_account_contract.ts index 134c58082b8..c5fd04c8ec4 100644 --- a/yarn-project/aztec.js/src/account/contract/auth_witness_account_contract.ts +++ b/yarn-project/aztec.js/src/account/contract/auth_witness_account_contract.ts @@ -1,6 +1,6 @@ import { Schnorr } from '@aztec/circuits.js/barretenberg'; import { ContractAbi } from '@aztec/foundation/abi'; -import { CompleteAddress, NodeInfo, PrivateKey } from '@aztec/types'; +import { CompleteAddress, GrumpkinPrivateKey, NodeInfo } from '@aztec/types'; import AuthWitnessAccountContractAbi from '../../abis/schnorr_auth_witness_account_contract.json' assert { type: 'json' }; import { AuthWitnessAccountEntrypoint } from '../entrypoint/auth_witness_account_entrypoint.js'; @@ -12,7 +12,7 @@ import { AccountContract } from './index.js'; * Extended to pull verification data from the oracle instead of passed as arguments. */ export class AuthWitnessAccountContract implements AccountContract { - constructor(private encryptionPrivateKey: PrivateKey) {} + constructor(private encryptionPrivateKey: GrumpkinPrivateKey) {} public getDeploymentArgs() { return Promise.resolve([]); diff --git a/yarn-project/aztec.js/src/account/contract/ecdsa_account_contract.ts b/yarn-project/aztec.js/src/account/contract/ecdsa_account_contract.ts index f2afb5793fd..56275c424be 100644 --- a/yarn-project/aztec.js/src/account/contract/ecdsa_account_contract.ts +++ b/yarn-project/aztec.js/src/account/contract/ecdsa_account_contract.ts @@ -1,6 +1,6 @@ import { Ecdsa } from '@aztec/circuits.js/barretenberg'; import { ContractAbi } from '@aztec/foundation/abi'; -import { CompleteAddress, NodeInfo, PrivateKey } from '@aztec/types'; +import { CompleteAddress, NodeInfo } from '@aztec/types'; import EcdsaAccountContractAbi from '../../abis/ecdsa_account_contract.json' assert { type: 'json' }; import { StoredKeyAccountEntrypoint } from '../entrypoint/stored_key_account_entrypoint.js'; @@ -10,7 +10,7 @@ import { AccountContract } from './index.js'; * Account contract that authenticates transactions using ECDSA signatures * verified against a secp256k1 public key stored in an immutable encrypted note. */ export class EcdsaAccountContract implements AccountContract { - constructor(private signingPrivateKey: PrivateKey) {} + constructor(private signingPrivateKey: Buffer) {} public async getDeploymentArgs() { const signingPublicKey = await Ecdsa.new().then(e => e.computePublicKey(this.signingPrivateKey)); @@ -18,7 +18,9 @@ import { AccountContract } from './index.js'; } public async getEntrypoint({ address }: CompleteAddress, { chainId, version }: NodeInfo) { - return new StoredKeyAccountEntrypoint(address, this.signingPrivateKey, await Ecdsa.new(), chainId, version); + const ecdsa = await Ecdsa.new(); + const signClosure = (msg: Buffer) => ecdsa.constructSignature(msg, this.signingPrivateKey); + return new StoredKeyAccountEntrypoint(address, signClosure, chainId, version); } public getContractAbi(): ContractAbi { diff --git a/yarn-project/aztec.js/src/account/contract/schnorr_account_contract.ts b/yarn-project/aztec.js/src/account/contract/schnorr_account_contract.ts index fcf711c8338..b12d7c4e97e 100644 --- a/yarn-project/aztec.js/src/account/contract/schnorr_account_contract.ts +++ b/yarn-project/aztec.js/src/account/contract/schnorr_account_contract.ts @@ -1,6 +1,6 @@ import { Schnorr } from '@aztec/circuits.js/barretenberg'; import { ContractAbi } from '@aztec/foundation/abi'; -import { CompleteAddress, NodeInfo, PrivateKey } from '@aztec/types'; +import { CompleteAddress, GrumpkinPrivateKey, NodeInfo } from '@aztec/types'; import SchnorrAccountContractAbi from '../../abis/schnorr_account_contract.json' assert { type: 'json' }; import { StoredKeyAccountEntrypoint } from '../entrypoint/stored_key_account_entrypoint.js'; @@ -11,7 +11,7 @@ import { AccountContract } from './index.js'; * verified against a Grumpkin public key stored in an immutable encrypted note. */ export class SchnorrAccountContract implements AccountContract { - constructor(private signingPrivateKey: PrivateKey) {} + constructor(private signingPrivateKey: GrumpkinPrivateKey) {} public async getDeploymentArgs() { const signingPublicKey = await Schnorr.new().then(e => e.computePublicKey(this.signingPrivateKey)); @@ -19,7 +19,9 @@ export class SchnorrAccountContract implements AccountContract { } public async getEntrypoint({ address }: CompleteAddress, { chainId, version }: NodeInfo) { - return new StoredKeyAccountEntrypoint(address, this.signingPrivateKey, await Schnorr.new(), chainId, version); + const schnorr = await Schnorr.new(); + const signClosure = (msg: Buffer) => schnorr.constructSignature(msg, this.signingPrivateKey); + return new StoredKeyAccountEntrypoint(address, signClosure, chainId, version); } public getContractAbi(): ContractAbi { diff --git a/yarn-project/aztec.js/src/account/contract/single_key_account_contract.ts b/yarn-project/aztec.js/src/account/contract/single_key_account_contract.ts index b9ec2bf5193..296988e46d0 100644 --- a/yarn-project/aztec.js/src/account/contract/single_key_account_contract.ts +++ b/yarn-project/aztec.js/src/account/contract/single_key_account_contract.ts @@ -1,6 +1,5 @@ -import { Schnorr } from '@aztec/circuits.js/barretenberg'; import { ContractAbi } from '@aztec/foundation/abi'; -import { CompleteAddress, NodeInfo, PrivateKey } from '@aztec/types'; +import { CompleteAddress, GrumpkinPrivateKey, NodeInfo } from '@aztec/types'; import SchnorrSingleKeyAccountContractAbi from '../../abis/schnorr_single_key_account_contract.json' assert { type: 'json' }; import { SingleKeyAccountEntrypoint } from '../entrypoint/single_key_account_entrypoint.js'; @@ -11,20 +10,15 @@ import { AccountContract } from './index.js'; * the note encryption key, relying on a single private key for both encryption and authentication. */ export class SingleKeyAccountContract implements AccountContract { - constructor(private encryptionPrivateKey: PrivateKey) {} + constructor(private encryptionPrivateKey: GrumpkinPrivateKey) {} public getDeploymentArgs() { return Promise.resolve([]); } - public async getEntrypoint({ address, partialAddress }: CompleteAddress, { chainId, version }: NodeInfo) { - return new SingleKeyAccountEntrypoint( - address, - partialAddress, - this.encryptionPrivateKey, - await Schnorr.new(), - chainId, - version, + public getEntrypoint({ address, partialAddress }: CompleteAddress, { chainId, version }: NodeInfo) { + return Promise.resolve( + new SingleKeyAccountEntrypoint(address, partialAddress, this.encryptionPrivateKey, chainId, version), ); } diff --git a/yarn-project/aztec.js/src/account/entrypoint/auth_witness_account_entrypoint.ts b/yarn-project/aztec.js/src/account/entrypoint/auth_witness_account_entrypoint.ts index c4a6f4915f2..a92b7194887 100644 --- a/yarn-project/aztec.js/src/account/entrypoint/auth_witness_account_entrypoint.ts +++ b/yarn-project/aztec.js/src/account/entrypoint/auth_witness_account_entrypoint.ts @@ -1,5 +1,5 @@ -import { AztecAddress, Fr, FunctionData, PartialAddress, PrivateKey, TxContext } from '@aztec/circuits.js'; -import { Signer } from '@aztec/circuits.js/barretenberg'; +import { AztecAddress, Fr, FunctionData, GrumpkinPrivateKey, PartialAddress, TxContext } from '@aztec/circuits.js'; +import { Schnorr } from '@aztec/circuits.js/barretenberg'; import { ContractAbi, FunctionAbi, encodeArguments } from '@aztec/foundation/abi'; import { FunctionCall, PackedArguments, TxExecutionRequest } from '@aztec/types'; @@ -19,8 +19,8 @@ export class AuthWitnessAccountEntrypoint implements Entrypoint { constructor( private address: AztecAddress, private partialAddress: PartialAddress, - private privateKey: PrivateKey, - private signer: Signer, + private privateKey: GrumpkinPrivateKey, + private signer: Schnorr, private chainId: number = DEFAULT_CHAIN_ID, private version: number = DEFAULT_VERSION, ) {} diff --git a/yarn-project/aztec.js/src/account/entrypoint/single_key_account_entrypoint.ts b/yarn-project/aztec.js/src/account/entrypoint/single_key_account_entrypoint.ts index 9e500d715b3..edd6943b445 100644 --- a/yarn-project/aztec.js/src/account/entrypoint/single_key_account_entrypoint.ts +++ b/yarn-project/aztec.js/src/account/entrypoint/single_key_account_entrypoint.ts @@ -1,5 +1,5 @@ -import { AztecAddress, FunctionData, PartialAddress, PrivateKey, TxContext } from '@aztec/circuits.js'; -import { Signer } from '@aztec/circuits.js/barretenberg'; +import { AztecAddress, FunctionData, GrumpkinPrivateKey, PartialAddress, TxContext } from '@aztec/circuits.js'; +import { Schnorr } from '@aztec/circuits.js/barretenberg'; import { ContractAbi, encodeArguments } from '@aztec/foundation/abi'; import { FunctionCall, PackedArguments, TxExecutionRequest } from '@aztec/types'; @@ -18,8 +18,7 @@ export class SingleKeyAccountEntrypoint implements Entrypoint { constructor( private address: AztecAddress, private partialAddress: PartialAddress, - private privateKey: PrivateKey, - private signer: Signer, + private privateKey: GrumpkinPrivateKey, private chainId: number = DEFAULT_CHAIN_ID, private version: number = DEFAULT_VERSION, ) {} @@ -35,7 +34,8 @@ export class SingleKeyAccountEntrypoint implements Entrypoint { const { payload, packedArguments: callsPackedArguments } = await buildPayload(executions); const message = await hashPayload(payload); - const signature = this.signer.constructSignature(message, this.privateKey).toBuffer(); + const signer = await Schnorr.new(); + const signature = signer.constructSignature(message, this.privateKey).toBuffer(); const publicKey = await generatePublicKey(this.privateKey); const args = [payload, publicKey.toBuffer(), signature, this.partialAddress]; const abi = this.getEntrypointAbi(); diff --git a/yarn-project/aztec.js/src/account/entrypoint/stored_key_account_entrypoint.ts b/yarn-project/aztec.js/src/account/entrypoint/stored_key_account_entrypoint.ts index f86e04d9095..0d6f195df47 100644 --- a/yarn-project/aztec.js/src/account/entrypoint/stored_key_account_entrypoint.ts +++ b/yarn-project/aztec.js/src/account/entrypoint/stored_key_account_entrypoint.ts @@ -1,5 +1,5 @@ -import { AztecAddress, FunctionData, PrivateKey, TxContext } from '@aztec/circuits.js'; -import { Signer } from '@aztec/circuits.js/barretenberg'; +import { AztecAddress, FunctionData, TxContext } from '@aztec/circuits.js'; +import { Signature } from '@aztec/circuits.js/barretenberg'; import { ContractAbi, encodeArguments } from '@aztec/foundation/abi'; import { DebugLogger, createDebugLogger } from '@aztec/foundation/log'; import { FunctionCall, PackedArguments, TxExecutionRequest } from '@aztec/types'; @@ -18,8 +18,7 @@ export class StoredKeyAccountEntrypoint implements Entrypoint { constructor( private address: AztecAddress, - private privateKey: PrivateKey, - private signer: Signer, + private sign: (msg: Buffer) => Signature, private chainId: number = DEFAULT_CHAIN_ID, private version: number = DEFAULT_VERSION, ) { @@ -36,7 +35,7 @@ export class StoredKeyAccountEntrypoint implements Entrypoint { const { payload, packedArguments: callsPackedArguments } = await buildPayload(executions); const message = await hashPayload(payload); - const signature = this.signer.constructSignature(message, this.privateKey).toBuffer(); + const signature = this.sign(message).toBuffer(); this.log(`Signed challenge ${message.toString('hex')} as ${signature.toString('hex')}`); const args = [payload, signature]; diff --git a/yarn-project/aztec.js/src/account/index.ts b/yarn-project/aztec.js/src/account/index.ts index 6794922ac68..83260ff9c08 100644 --- a/yarn-project/aztec.js/src/account/index.ts +++ b/yarn-project/aztec.js/src/account/index.ts @@ -1,4 +1,4 @@ -import { AztecRPC, CompleteAddress, PrivateKey } from '@aztec/types'; +import { AztecRPC, CompleteAddress, GrumpkinPrivateKey } from '@aztec/types'; import { AccountContract, AccountWallet, AztecAddress, Fr } from '../index.js'; import { Account } from './account.js'; @@ -23,8 +23,8 @@ export type Salt = Fr | number | bigint; */ export function getEcdsaAccount( rpc: AztecRPC, - encryptionPrivateKey: PrivateKey, - signingPrivateKey: PrivateKey, + encryptionPrivateKey: GrumpkinPrivateKey, + signingPrivateKey: Buffer, saltOrAddress?: Salt | CompleteAddress, ): Account { return new Account(rpc, encryptionPrivateKey, new EcdsaAccountContract(signingPrivateKey), saltOrAddress); @@ -39,8 +39,8 @@ export function getEcdsaAccount( */ export function getSchnorrAccount( rpc: AztecRPC, - encryptionPrivateKey: PrivateKey, - signingPrivateKey: PrivateKey, + encryptionPrivateKey: GrumpkinPrivateKey, + signingPrivateKey: GrumpkinPrivateKey, saltOrAddress?: Salt | CompleteAddress, ): Account { return new Account(rpc, encryptionPrivateKey, new SchnorrAccountContract(signingPrivateKey), saltOrAddress); @@ -54,7 +54,7 @@ export function getSchnorrAccount( */ export function getUnsafeSchnorrAccount( rpc: AztecRPC, - encryptionAndSigningPrivateKey: PrivateKey, + encryptionAndSigningPrivateKey: GrumpkinPrivateKey, saltOrAddress?: Salt | CompleteAddress, ): Account { return new Account( @@ -75,7 +75,7 @@ export function getUnsafeSchnorrAccount( export function getUnsafeSchnorrWallet( rpc: AztecRPC, address: AztecAddress, - signingKey: PrivateKey, + signingKey: GrumpkinPrivateKey, ): Promise { return getWallet(rpc, address, new SingleKeyAccountContract(signingKey)); } diff --git a/yarn-project/aztec.js/src/aztec_rpc_client/aztec_rpc_client.ts b/yarn-project/aztec.js/src/aztec_rpc_client/aztec_rpc_client.ts index 075a14c9703..fcd50d72788 100644 --- a/yarn-project/aztec.js/src/aztec_rpc_client/aztec_rpc_client.ts +++ b/yarn-project/aztec.js/src/aztec_rpc_client/aztec_rpc_client.ts @@ -1,4 +1,4 @@ -import { AztecAddress, CompleteAddress, EthAddress, Fr, Point, PrivateKey } from '@aztec/circuits.js'; +import { AztecAddress, CompleteAddress, EthAddress, Fr, GrumpkinScalar, Point } from '@aztec/circuits.js'; import { createJsonRpcClient, defaultFetch } from '@aztec/foundation/json-rpc/client'; import { AztecRPC, @@ -26,8 +26,8 @@ export const createAztecRpcClient = (url: string, fetch = defaultFetch): AztecRP TxHash, EthAddress, Point, - PrivateKey, Fr, + GrumpkinScalar, NotePreimage, }, { Tx, TxReceipt, L2BlockL2Logs }, diff --git a/yarn-project/aztec.js/src/aztec_rpc_client/wallet.ts b/yarn-project/aztec.js/src/aztec_rpc_client/wallet.ts index ee68855657f..7b7df529c0c 100644 --- a/yarn-project/aztec.js/src/aztec_rpc_client/wallet.ts +++ b/yarn-project/aztec.js/src/aztec_rpc_client/wallet.ts @@ -1,4 +1,4 @@ -import { AztecAddress, CircuitsWasm, Fr, PartialAddress, PrivateKey, TxContext } from '@aztec/circuits.js'; +import { AztecAddress, CircuitsWasm, Fr, GrumpkinPrivateKey, PartialAddress, TxContext } from '@aztec/circuits.js'; import { AztecRPC, ContractData, @@ -32,7 +32,7 @@ export abstract class BaseWallet implements Wallet { abstract createTxExecutionRequest(execs: FunctionCall[], opts?: CreateTxRequestOpts): Promise; - registerAccount(privKey: PrivateKey, partialAddress: PartialAddress): Promise { + registerAccount(privKey: GrumpkinPrivateKey, partialAddress: PartialAddress): Promise { return this.rpc.registerAccount(privKey, partialAddress); } registerRecipient(account: CompleteAddress): Promise { diff --git a/yarn-project/aztec.js/src/index.ts b/yarn-project/aztec.js/src/index.ts index 79307f9a9a5..fdc2102017b 100644 --- a/yarn-project/aztec.js/src/index.ts +++ b/yarn-project/aztec.js/src/index.ts @@ -6,7 +6,7 @@ export * from './account/index.js'; export * from './contract_deployer/deploy_method.js'; export * from './sandbox/index.js'; -export { AztecAddress, EthAddress, Point, Fr } from '@aztec/circuits.js'; +export { AztecAddress, EthAddress, Point, Fr, GrumpkinScalar } from '@aztec/circuits.js'; export { AztecRPC, ContractData, @@ -17,7 +17,7 @@ export { NodeInfo, PackedArguments, PublicKey, - PrivateKey, + GrumpkinPrivateKey, SyncStatus, Tx, TxExecutionRequest, diff --git a/yarn-project/aztec.js/src/sandbox/index.ts b/yarn-project/aztec.js/src/sandbox/index.ts index c0790b63960..814218c3a12 100644 --- a/yarn-project/aztec.js/src/sandbox/index.ts +++ b/yarn-project/aztec.js/src/sandbox/index.ts @@ -1,4 +1,4 @@ -import { Fr, PrivateKey } from '@aztec/circuits.js'; +import { Fr, GrumpkinScalar } from '@aztec/circuits.js'; import { ContractAbi } from '@aztec/foundation/abi'; import { sleep } from '@aztec/foundation/sleep'; @@ -8,9 +8,9 @@ import SchnorrAccountContractAbi from '../abis/schnorr_account_contract.json' as import { AccountWallet, AztecRPC, EntrypointWallet, getAccountWallets, getSchnorrAccount } from '../index.js'; export const INITIAL_SANDBOX_ENCRYPTION_KEYS = [ - new PrivateKey(Buffer.from('b2803ec899f76f6b2ac011480d24028f1a29587f8a3a92f7ee9d48d8c085c284', 'hex')), - new PrivateKey(Buffer.from('6bb46e9a80da2ff7bfff71c2c50eaaa4b15f7ed5ad1ade4261b574ef80b0cdb0', 'hex')), - new PrivateKey(Buffer.from('0f6addf0da06c33293df974a565b03d1ab096090d907d98055a8b7f4954e120c', 'hex')), + GrumpkinScalar.fromString('2153536ff6628eee01cf4024889ff977a18d9fa61d0e414422f7681cf085c281'), + GrumpkinScalar.fromString('aebd1b4be76efa44f5ee655c20bf9ea60f7ae44b9a7fd1fd9f189c7a0b0cdae'), + GrumpkinScalar.fromString('0f6addf0da06c33293df974a565b03d1ab096090d907d98055a8b7f4954e120c'), ]; export const INITIAL_SANDBOX_SIGNING_KEYS = INITIAL_SANDBOX_ENCRYPTION_KEYS; diff --git a/yarn-project/aztec.js/src/utils/account.ts b/yarn-project/aztec.js/src/utils/account.ts index 1272cddb3d2..baa0b5110f1 100644 --- a/yarn-project/aztec.js/src/utils/account.ts +++ b/yarn-project/aztec.js/src/utils/account.ts @@ -1,4 +1,4 @@ -import { Fr, PrivateKey, getContractDeploymentInfo } from '@aztec/circuits.js'; +import { Fr, GrumpkinPrivateKey, GrumpkinScalar, getContractDeploymentInfo } from '@aztec/circuits.js'; import { Schnorr } from '@aztec/circuits.js/barretenberg'; import { ContractAbi } from '@aztec/foundation/abi'; import { createDebugLogger } from '@aztec/foundation/log'; @@ -15,7 +15,7 @@ import { ContractDeployer, EntrypointCollection, StoredKeyAccountEntrypoint, gen export async function createAccounts( aztecRpcClient: AztecRPC, accountContractAbi: ContractAbi, - privateKey?: PrivateKey, + privateKey?: GrumpkinPrivateKey, salt = Fr.random(), numberOfAccounts = 1, logger = createDebugLogger('aztec:aztec.js:accounts'), @@ -24,7 +24,7 @@ export async function createAccounts( for (let i = 0; i < numberOfAccounts; ++i) { // TODO(#662): Let the aztec rpc server generate the keypair rather than hardcoding the private key - const privKey = i == 0 && privateKey ? privateKey : PrivateKey.random(); + const privKey = i == 0 && privateKey ? privateKey : GrumpkinScalar.random(); const publicKey = await generatePublicKey(privKey); const deploymentInfo = await getContractDeploymentInfo(accountContractAbi, [], salt, publicKey); await aztecRpcClient.registerAccount(privKey, deploymentInfo.completeAddress.partialAddress); @@ -44,12 +44,7 @@ export async function createAccounts( logger(`Created account ${address.toString()} with public key ${publicKey.toString()}`); accountImpls.registerAccount( address, - new SingleKeyAccountEntrypoint( - address, - deploymentInfo.completeAddress.partialAddress, - privKey, - await Schnorr.new(), - ), + new SingleKeyAccountEntrypoint(address, deploymentInfo.completeAddress.partialAddress, privKey), ); } return new EntrypointWallet(aztecRpcClient, accountImpls); @@ -67,14 +62,16 @@ export async function createAccounts( export async function getAccountWallets( aztecRpcClient: AztecRPC, accountContractAbi: ContractAbi, - privateKeys: PrivateKey[], - signingKeys: PrivateKey[], + privateKeys: GrumpkinPrivateKey[], + signingKeys: GrumpkinPrivateKey[], salts: Fr[], ) { if (privateKeys.length != salts.length || signingKeys.length != privateKeys.length) { throw new Error('Keys and salts must be the same length'); } const accountCollection = new EntrypointCollection(); + const schnorr = await Schnorr.new(); + for (let i = 0; i < privateKeys.length; i++) { const publicKey = await generatePublicKey(privateKeys[i]); const signingPublicKey = await generatePublicKey(signingKeys[i]); @@ -86,10 +83,9 @@ export async function getAccountWallets( ); const address = deploymentInfo.completeAddress.address; - accountCollection.registerAccount( - address, - new StoredKeyAccountEntrypoint(address, signingKeys[i], await Schnorr.new()), - ); + const signClosure = (msg: Buffer) => schnorr.constructSignature(msg, signingKeys[i]); + + accountCollection.registerAccount(address, new StoredKeyAccountEntrypoint(address, signClosure)); } return new EntrypointWallet(aztecRpcClient, accountCollection); } diff --git a/yarn-project/aztec.js/src/utils/pub_key.ts b/yarn-project/aztec.js/src/utils/pub_key.ts index 01a60a75357..14b317569de 100644 --- a/yarn-project/aztec.js/src/utils/pub_key.ts +++ b/yarn-project/aztec.js/src/utils/pub_key.ts @@ -1,4 +1,4 @@ -import { PrivateKey, PublicKey } from '@aztec/circuits.js'; +import { GrumpkinPrivateKey, PublicKey } from '@aztec/circuits.js'; import { Grumpkin } from '@aztec/circuits.js/barretenberg'; /** @@ -6,7 +6,7 @@ import { Grumpkin } from '@aztec/circuits.js/barretenberg'; * @param privateKey - The private key. * @returns The generated public key. */ -export async function generatePublicKey(privateKey: PrivateKey): Promise { +export async function generatePublicKey(privateKey: GrumpkinPrivateKey): Promise { const grumpkin = await Grumpkin.new(); return grumpkin.mul(grumpkin.generator(), privateKey); } diff --git a/yarn-project/canary/README.md b/yarn-project/canary/README.md index 035272f6777..3ff4851a9ec 100644 --- a/yarn-project/canary/README.md +++ b/yarn-project/canary/README.md @@ -10,6 +10,6 @@ To build and execute the test: `export FORK_BLOCK_NUMBER=17514288` `export FORK_URL='https://mainnet.infura.io/v3/9928b52099854248b3a096be07a6b23c'` -`docker build --build-arg COMMIT_TAG= .` +`docker build --build-arg COMMIT_TAG= .` `cd ./scripts` `docker-compose up` diff --git a/yarn-project/canary/scripts/cond_run_script b/yarn-project/canary/scripts/cond_run_script new file mode 100755 index 00000000000..88bf7d5c4b6 --- /dev/null +++ b/yarn-project/canary/scripts/cond_run_script @@ -0,0 +1,34 @@ +#!/bin/bash +# Conditionally runs a script if any dependent code has changed between +# the last successful run and the present commit. +# +# It's expected to be run from the project directory, and that there be a directory called `scripts` +# containing the given named script to execute. +# +# This script is only useful if there is nothing to do in the event there is no rebuild. This is fine +# for running a suite of tests for example, but is not useful for performing a build, as even if a +# build has nothing to do, the previous images are retagged with the new commit hash for upstream jobs. +# +# Arguments are: +# 1. REPOSITORY: The project repository name in ECR. Used to determine if there are changes since last success. +# 2. SUCCESS_TAG: To track if this job needs to be run, the repository image is tagged with a success tag after a +# successful run. The script will only run if there were relevant code changes since the last successful commit. +# 3... ARGS: Script to run and args. +set -eu +set -x + +REPOSITORY=$1 +shift +SUCCESS_TAG=$1 +shift +SCRIPT_TO_RUN=$1 +shift + +CONTENT_HASH=$(calculate_content_hash $REPOSITORY) +echo "Content hash tag: cache-$CONTENT_HASH-$SUCCESS_TAG" +echo "Script to run is $SCRIPT_TO_RUN $@" + +if ! check_rebuild cache-$CONTENT_HASH-$SUCCESS_TAG $REPOSITORY; then + "$SCRIPT_TO_RUN" "$@" + tag_remote_image $REPOSITORY cache-$CONTENT_HASH cache-$CONTENT_HASH-$SUCCESS_TAG +fi diff --git a/yarn-project/canary/scripts/run_tests b/yarn-project/canary/scripts/run_tests index e2fd492f287..e69104373c6 100755 --- a/yarn-project/canary/scripts/run_tests +++ b/yarn-project/canary/scripts/run_tests @@ -5,14 +5,14 @@ set -eu export TEST=$1 export IMAGE=${2:-canary} -export COMPOSE_FILE=${3:-docker-compose.yml} +export COMPOSE_FILE=${3:-./scripts/docker-compose.yml} if [ "$TEST" = "uniswap_trade_on_l1_from_l2.test.ts" ]; then export FORK_URL=https://mainnet.infura.io/v3/9928b52099854248b3a096be07a6b23c export FORK_BLOCK_NUMBER=17514288 fi -$(aws ecr get-login --region us-east-2 --no-include-email) 2> /dev/null +aws ecr get-login-password --region us-east-2 | docker login --username AWS --password-stdin 278380418400.dkr.ecr.us-east-2.amazonaws.com IMAGE_URI=$($(git rev-parse --show-toplevel)/build-system/scripts/calculate_image_uri $IMAGE) docker pull $IMAGE_URI @@ -22,5 +22,5 @@ SANDBOX_IMAGE_URI=$($(git rev-parse --show-toplevel)/build-system/scripts/calcul docker pull $SANDBOX_IMAGE_URI docker tag $SANDBOX_IMAGE_URI aztecprotocol/sandbox:latest -docker-compose rm -f +docker-compose -f $COMPOSE_FILE rm -f docker-compose -f $COMPOSE_FILE up --exit-code-from canary diff --git a/yarn-project/canary/src/aztec_js_browser.test.ts b/yarn-project/canary/src/aztec_js_browser.test.ts index 11b7d4ebffc..525b9ca217d 100644 --- a/yarn-project/canary/src/aztec_js_browser.test.ts +++ b/yarn-project/canary/src/aztec_js_browser.test.ts @@ -1,6 +1,6 @@ /* eslint-disable no-console */ import * as AztecJs from '@aztec/aztec.js'; -import { AztecAddress, PrivateKey } from '@aztec/circuits.js'; +import { AztecAddress, GrumpkinScalar } from '@aztec/circuits.js'; import { DebugLogger, createDebugLogger } from '@aztec/foundation/log'; import { fileURLToPath } from '@aztec/foundation/url'; import { PrivateTokenContractAbi } from '@aztec/noir-contracts/artifacts'; @@ -25,7 +25,7 @@ const PORT = 3000; const { SANDBOX_URL } = process.env; const conditionalDescribe = () => (SANDBOX_URL ? describe : describe.skip); -const privKey = PrivateKey.random(); +const privKey = GrumpkinScalar.random(); /** * This test is a bit of a special case as it's relying on sandbox and web browser and not only on anvil and node.js. @@ -110,9 +110,9 @@ conditionalDescribe()('e2e_aztec.js_browser', () => { it('Creates an account', async () => { const result = await page.evaluate( async (rpcUrl, privateKeyString) => { - const { PrivateKey, createAztecRpcClient, makeFetch, getUnsafeSchnorrAccount } = window.AztecJs; + const { GrumpkinScalar, createAztecRpcClient, makeFetch, getUnsafeSchnorrAccount } = window.AztecJs; const client = createAztecRpcClient(rpcUrl!, makeFetch([1, 2, 3], true)); - const privateKey = PrivateKey.fromString(privateKeyString); + const privateKey = GrumpkinScalar.fromString(privateKeyString); const account = getUnsafeSchnorrAccount(client, privateKey); await account.waitDeploy(); const completeAddress = await account.getCompleteAddress(); @@ -177,12 +177,13 @@ conditionalDescribe()('e2e_aztec.js_browser', () => { const deployPrivateTokenContract = async () => { const txHash = await page.evaluate( async (rpcUrl, privateKeyString, initialBalance, PrivateTokenContractAbi) => { - const { PrivateKey, DeployMethod, createAztecRpcClient, makeFetch, getUnsafeSchnorrAccount } = window.AztecJs; + const { GrumpkinScalar, DeployMethod, createAztecRpcClient, makeFetch, getUnsafeSchnorrAccount } = + window.AztecJs; const client = createAztecRpcClient(rpcUrl!, makeFetch([1, 2, 3], true)); let accounts = await client.getAccounts(); if (accounts.length === 0) { // This test needs an account for deployment. We create one in case there is none available in the RPC server. - const privateKey = PrivateKey.fromString(privateKeyString); + const privateKey = GrumpkinScalar.fromString(privateKeyString); await getUnsafeSchnorrAccount(client, privateKey).waitDeploy(); accounts = await client.getAccounts(); } diff --git a/yarn-project/canary/src/uniswap_trade_on_l1_from_l2.test.ts b/yarn-project/canary/src/uniswap_trade_on_l1_from_l2.test.ts index 7f630728e37..350f01656ca 100644 --- a/yarn-project/canary/src/uniswap_trade_on_l1_from_l2.test.ts +++ b/yarn-project/canary/src/uniswap_trade_on_l1_from_l2.test.ts @@ -2,7 +2,6 @@ import { AztecAddress, EthAddress, Fr, - PrivateKey, TxStatus, Wallet, computeMessageSecretHash, @@ -51,7 +50,6 @@ const aztecRpcUrl = SANDBOX_URL; const ethRpcUrl = ETHEREUM_HOST; const hdAccount = mnemonicToAccount(MNEMONIC); -const privateKey = new PrivateKey(Buffer.from(hdAccount.getHdKey().privateKey!)); const aztecRpcClient = createAztecRpcClient(aztecRpcUrl, makeFetch([1, 2, 3], true)); let wallet: Wallet; diff --git a/yarn-project/circuits.js/src/barretenberg/crypto/ecdsa/index.test.ts b/yarn-project/circuits.js/src/barretenberg/crypto/ecdsa/index.test.ts index f501df84210..a05f16f9b8c 100644 --- a/yarn-project/circuits.js/src/barretenberg/crypto/ecdsa/index.test.ts +++ b/yarn-project/circuits.js/src/barretenberg/crypto/ecdsa/index.test.ts @@ -1,6 +1,6 @@ import { TextEncoder } from 'util'; -import { CircuitsWasm, PrivateKey } from '../../../index.js'; +import { CircuitsWasm } from '../../../index.js'; import { Ecdsa } from './index.js'; describe('ecdsa', () => { @@ -13,10 +13,10 @@ describe('ecdsa', () => { it('should verify signature', () => { // prettier-ignore - const privateKey = new PrivateKey(Buffer.from([ + const privateKey = Buffer.from([ 0x0b, 0x9b, 0x3a, 0xde, 0xe6, 0xb3, 0xd8, 0x1b, 0x28, 0xa0, 0x88, 0x6b, 0x2a, 0x84, 0x15, 0xc7, 0xda, 0x31, 0x29, 0x1a, 0x5e, 0x96, 0xbb, 0x7a, 0x56, 0x63, 0x9e, 0x17, 0x7d, 0x30, 0x1b, 0xeb, - ])); + ]); const pubKey = ecdsa.computePublicKey(privateKey); const msg = new TextEncoder().encode('The quick brown dog jumped over the lazy fox.'); const signature = ecdsa.constructSignature(msg, privateKey); @@ -27,10 +27,10 @@ describe('ecdsa', () => { it('should recover public key from signature', () => { // prettier-ignore - const privateKey = new PrivateKey(Buffer.from([ + const privateKey = Buffer.from([ 0x0b, 0x9b, 0x3a, 0xde, 0xe6, 0xb3, 0xd8, 0x1b, 0x28, 0xa0, 0x88, 0x6b, 0x2a, 0x84, 0x15, 0xc7, 0xda, 0x31, 0x29, 0x1a, 0x5e, 0x96, 0xbb, 0x7a, 0x56, 0x63, 0x9e, 0x17, 0x7d, 0x30, 0x1b, 0xeb, - ])); + ]); const pubKey = ecdsa.computePublicKey(privateKey); const msg = new TextEncoder().encode('The quick brown dog jumped over the lazy fox...'); const signature = ecdsa.constructSignature(msg, privateKey); diff --git a/yarn-project/circuits.js/src/barretenberg/crypto/ecdsa/index.ts b/yarn-project/circuits.js/src/barretenberg/crypto/ecdsa/index.ts index 65844825386..6efa8cc5568 100644 --- a/yarn-project/circuits.js/src/barretenberg/crypto/ecdsa/index.ts +++ b/yarn-project/circuits.js/src/barretenberg/crypto/ecdsa/index.ts @@ -1,7 +1,6 @@ import { IWasmModule } from '@aztec/foundation/wasm'; -import { CircuitsWasm, PrivateKey } from '../../../index.js'; -import { Signer } from '../index.js'; +import { CircuitsWasm } from '../../../index.js'; import { EcdsaSignature } from './signature.js'; export * from './signature.js'; @@ -9,7 +8,7 @@ export * from './signature.js'; /** * ECDSA signature construction and helper operations. */ -export class Ecdsa implements Signer { +export class Ecdsa { /** * Creates a new Ecdsa instance. * @returns New Ecdsa instance. @@ -25,8 +24,8 @@ export class Ecdsa implements Signer { * @param privateKey - Secp256k1 private key. * @returns A secp256k1 public key. */ - public computePublicKey(privateKey: PrivateKey): Buffer { - this.wasm.writeMemory(0, privateKey.value); + public computePublicKey(privateKey: Buffer): Buffer { + this.wasm.writeMemory(0, privateKey); this.wasm.call('ecdsa__compute_public_key', 0, 32); return Buffer.from(this.wasm.getMemorySlice(32, 96)); } @@ -37,9 +36,9 @@ export class Ecdsa implements Signer { * @param privateKey - The secp256k1 private key of the signer. * @returns An ECDSA signature of the form (r, s, v). */ - public constructSignature(msg: Uint8Array, privateKey: PrivateKey) { + public constructSignature(msg: Uint8Array, privateKey: Buffer) { const mem = this.wasm.call('bbmalloc', msg.length); - this.wasm.writeMemory(0, privateKey.value); + this.wasm.writeMemory(0, privateKey); this.wasm.writeMemory(mem, msg); this.wasm.call('ecdsa__construct_signature', mem, msg.length, 0, 32, 64, 96); diff --git a/yarn-project/circuits.js/src/barretenberg/crypto/grumpkin/index.test.ts b/yarn-project/circuits.js/src/barretenberg/crypto/grumpkin/index.test.ts index b1d582fda09..2a79d619b98 100644 --- a/yarn-project/circuits.js/src/barretenberg/crypto/grumpkin/index.test.ts +++ b/yarn-project/circuits.js/src/barretenberg/crypto/grumpkin/index.test.ts @@ -1,6 +1,6 @@ import { createDebugLogger } from '@aztec/foundation/log'; -import { CircuitsWasm, Point, PrivateKey } from '../../../index.js'; +import { CircuitsWasm, GrumpkinScalar, Point } from '../../../index.js'; import { Grumpkin } from './index.js'; const debug = createDebugLogger('bb:grumpkin_test'); @@ -15,13 +15,13 @@ describe('grumpkin', () => { }); it('should correctly perform scalar muls', () => { - const exponent = PrivateKey.random(); + const exponent = GrumpkinScalar.random(); const numPoints = 2048; const inputPoints: Point[] = []; for (let i = 0; i < numPoints; ++i) { - inputPoints.push(grumpkin.mul(Grumpkin.generator, PrivateKey.random())); + inputPoints.push(grumpkin.mul(Grumpkin.generator, GrumpkinScalar.random())); } const start = new Date().getTime(); diff --git a/yarn-project/circuits.js/src/barretenberg/crypto/grumpkin/index.ts b/yarn-project/circuits.js/src/barretenberg/crypto/grumpkin/index.ts index 5198a781143..d2967d772e0 100644 --- a/yarn-project/circuits.js/src/barretenberg/crypto/grumpkin/index.ts +++ b/yarn-project/circuits.js/src/barretenberg/crypto/grumpkin/index.ts @@ -1,6 +1,6 @@ import { IWasmModule } from '@aztec/foundation/wasm'; -import { CircuitsWasm, Fr, Point, PrivateKey } from '../../../index.js'; +import { CircuitsWasm, Fr, GrumpkinScalar, Point } from '../../../index.js'; /** * Grumpkin elliptic curve operations. @@ -33,32 +33,32 @@ export class Grumpkin { } /** - * Multiplies a point by a private key (adds the point `privateKey` amount of time). + * Multiplies a point by a scalar (adds the point `scalar` amount of times). * @param point - Point to multiply. - * @param privateKey - Private key to multiply by. + * @param scalar - Scalar to multiply by. * @returns Result of the multiplication. */ - public mul(point: Point, privateKey: PrivateKey): Point { + public mul(point: Point, scalar: GrumpkinScalar): Point { this.wasm.writeMemory(0, point.toBuffer()); - this.wasm.writeMemory(64, privateKey.value); + this.wasm.writeMemory(64, scalar.toBuffer()); this.wasm.call('ecc_grumpkin__mul', 0, 64, 96); return Point.fromBuffer(Buffer.from(this.wasm.getMemorySlice(96, 160))); } /** - * Multiplies a set of points by a private key. + * Multiplies a set of points by a scalar. * @param points - Points to multiply. - * @param privateKey - Private key to multiply by. - * @returns Points multiplied by the private key. + * @param scalar - Scalar to multiply by. + * @returns Points multiplied by the scalar. */ - public batchMul(points: Point[], privateKey: PrivateKey) { + public batchMul(points: Point[], scalar: GrumpkinScalar) { const concatenatedPoints: Buffer = Buffer.concat(points.map(point => point.toBuffer())); const pointsByteLength = points.length * Point.SIZE_IN_BYTES; const mem = this.wasm.call('bbmalloc', pointsByteLength * 2); this.wasm.writeMemory(mem, concatenatedPoints); - this.wasm.writeMemory(0, privateKey.value); + this.wasm.writeMemory(0, scalar.toBuffer()); this.wasm.call('ecc_grumpkin__batch_mul', mem, 0, points.length, mem + pointsByteLength); const result: Buffer = Buffer.from( diff --git a/yarn-project/circuits.js/src/barretenberg/crypto/schnorr/index.test.ts b/yarn-project/circuits.js/src/barretenberg/crypto/schnorr/index.test.ts index 2be6aca4173..c5a2b7b8687 100644 --- a/yarn-project/circuits.js/src/barretenberg/crypto/schnorr/index.test.ts +++ b/yarn-project/circuits.js/src/barretenberg/crypto/schnorr/index.test.ts @@ -1,6 +1,6 @@ import { TextEncoder } from 'util'; -import { CircuitsWasm, PrivateKey } from '../../../index.js'; +import { CircuitsWasm, GrumpkinScalar } from '../../../index.js'; import { Schnorr } from './index.js'; describe('schnorr', () => { @@ -12,7 +12,7 @@ describe('schnorr', () => { it('should verify signature', () => { // prettier-ignore - const privateKey = new PrivateKey(Buffer.from([ + const privateKey = GrumpkinScalar.fromBuffer(Buffer.from([ 0x0b, 0x9b, 0x3a, 0xde, 0xe6, 0xb3, 0xd8, 0x1b, 0x28, 0xa0, 0x88, 0x6b, 0x2a, 0x84, 0x15, 0xc7, 0xda, 0x31, 0x29, 0x1a, 0x5e, 0x96, 0xbb, 0x7a, 0x56, 0x63, 0x9e, 0x17, 0x7d, 0x30, 0x1b, 0xeb, ])); @@ -26,13 +26,13 @@ describe('schnorr', () => { it('should fail invalid signature', () => { // prettier-ignore - const privateKey = new PrivateKey(Buffer.from([ + const privateKey = GrumpkinScalar.fromBuffer(Buffer.from([ 0x0b, 0x9b, 0x3a, 0xde, 0xe6, 0xb3, 0xd8, 0x1b, 0x28, 0xa0, 0x88, 0x6b, 0x2a, 0x84, 0x15, 0xc7, 0xda, 0x31, 0x29, 0x1a, 0x5e, 0x96, 0xbb, 0x7a, 0x56, 0x63, 0x9e, 0x17, 0x7d, 0x30, 0x1b, 0xeb, ])); const pubKey = schnorr.computePublicKey(privateKey); const msg = new TextEncoder().encode('The quick brown dog jumped over the lazy fox.'); - const signature = schnorr.constructSignature(msg, PrivateKey.random()); + const signature = schnorr.constructSignature(msg, GrumpkinScalar.random()); const verified = schnorr.verifySignature(msg, pubKey, signature); expect(verified).toBe(false); diff --git a/yarn-project/circuits.js/src/barretenberg/crypto/schnorr/index.ts b/yarn-project/circuits.js/src/barretenberg/crypto/schnorr/index.ts index 8a97ee06d2c..e850d63e1d3 100644 --- a/yarn-project/circuits.js/src/barretenberg/crypto/schnorr/index.ts +++ b/yarn-project/circuits.js/src/barretenberg/crypto/schnorr/index.ts @@ -1,8 +1,7 @@ import { numToUInt32BE } from '@aztec/foundation/serialize'; import { IWasmModule } from '@aztec/foundation/wasm'; -import { CircuitsWasm, Point, PrivateKey, PublicKey } from '../../../index.js'; -import { Signer } from '../index.js'; +import { CircuitsWasm, GrumpkinPrivateKey, Point, PublicKey } from '../../../index.js'; import { SchnorrSignature } from './signature.js'; export * from './signature.js'; @@ -10,7 +9,7 @@ export * from './signature.js'; /** * Schnorr signature construction and helper operations. */ -export class Schnorr implements Signer { +export class Schnorr { /** * Creates a new Schnorr instance. * @returns New Schnorr instance. @@ -26,8 +25,8 @@ export class Schnorr implements Signer { * @param privateKey - The private key. * @returns A grumpkin public key. */ - public computePublicKey(privateKey: PrivateKey): PublicKey { - this.wasm.writeMemory(0, privateKey.value); + public computePublicKey(privateKey: GrumpkinPrivateKey): PublicKey { + this.wasm.writeMemory(0, privateKey.toBuffer()); this.wasm.call('schnorr_compute_public_key', 0, 32); return Point.fromBuffer(Buffer.from(this.wasm.getMemorySlice(32, 96))); } @@ -38,9 +37,9 @@ export class Schnorr implements Signer { * @param privateKey - The private key of the signer. * @returns A Schnorr signature of the form (s, e). */ - public constructSignature(msg: Uint8Array, privateKey: PrivateKey) { + public constructSignature(msg: Uint8Array, privateKey: GrumpkinPrivateKey) { const mem = this.wasm.call('bbmalloc', msg.length + 4); - this.wasm.writeMemory(0, privateKey.value); + this.wasm.writeMemory(0, privateKey.toBuffer()); this.wasm.writeMemory(mem, Buffer.concat([numToUInt32BE(msg.length), msg])); this.wasm.call('schnorr_construct_signature', mem, 0, 32, 64); diff --git a/yarn-project/circuits.js/src/barretenberg/crypto/secp256k1/index.test.ts b/yarn-project/circuits.js/src/barretenberg/crypto/secp256k1/index.test.ts index 87a856275b9..801b45d796e 100644 --- a/yarn-project/circuits.js/src/barretenberg/crypto/secp256k1/index.test.ts +++ b/yarn-project/circuits.js/src/barretenberg/crypto/secp256k1/index.test.ts @@ -1,4 +1,6 @@ -import { CircuitsWasm, PrivateKey } from '../../../index.js'; +import { randomBytes } from '@aztec/foundation/crypto'; + +import { CircuitsWasm } from '../../../index.js'; import { Ecdsa } from '../ecdsa/index.js'; import { Secp256k1 } from './index.js'; @@ -13,8 +15,8 @@ describe('secp256k1', () => { }); it('should correctly compute public key', () => { - const privateKey = PrivateKey.random(); - const lhs = secp256k1.mul(Secp256k1.generator, privateKey.value); + const privateKey = randomBytes(32); + const lhs = secp256k1.mul(Secp256k1.generator, privateKey); const rhs = ecdsa.computePublicKey(privateKey); expect(lhs).toEqual(rhs); }); diff --git a/yarn-project/circuits.js/src/barretenberg/crypto/signature/index.ts b/yarn-project/circuits.js/src/barretenberg/crypto/signature/index.ts index 506fc08c57a..1d76139464e 100644 --- a/yarn-project/circuits.js/src/barretenberg/crypto/signature/index.ts +++ b/yarn-project/circuits.js/src/barretenberg/crypto/signature/index.ts @@ -1,7 +1,5 @@ import { Fr } from '@aztec/foundation/fields'; -import { PrivateKey } from '../../../types/private_key.js'; - /** * Interface to represent a signature. */ @@ -17,16 +15,3 @@ export interface Signature { */ toFields(): Fr[]; } - -/** - * Interface to represent a signer. - */ -export interface Signer { - /** - * Signs the given message with the given private key. - * @param message - What to sign. - * @param privateKey - The private key. - * @returns A signature. - */ - constructSignature(message: Uint8Array, privateKey: PrivateKey): Signature; -} diff --git a/yarn-project/circuits.js/src/structs/membership_witness.ts b/yarn-project/circuits.js/src/structs/membership_witness.ts index 8065bba0232..2e24c61bf6c 100644 --- a/yarn-project/circuits.js/src/structs/membership_witness.ts +++ b/yarn-project/circuits.js/src/structs/membership_witness.ts @@ -41,7 +41,7 @@ export class MembershipWitness { /** * Creates a random membership witness. Used for testing purposes. - * @param pathSize - Number of fields in the siblin path. + * @param pathSize - Number of fields in the sibling path. * @returns Random membership witness. */ public static random(pathSize: N) { diff --git a/yarn-project/circuits.js/src/types/complete_address.ts b/yarn-project/circuits.js/src/types/complete_address.ts index 49c6da0fe46..0e4020c2f15 100644 --- a/yarn-project/circuits.js/src/types/complete_address.ts +++ b/yarn-project/circuits.js/src/types/complete_address.ts @@ -3,7 +3,7 @@ import { BufferReader } from '@aztec/foundation/serialize'; import { computeContractAddressFromPartial } from '../abis/abis.js'; import { Grumpkin } from '../barretenberg/index.js'; -import { CircuitsWasm, Fr, Point, PrivateKey } from '../index.js'; +import { CircuitsWasm, Fr, GrumpkinPrivateKey, Point } from '../index.js'; import { PartialAddress } from './partial_address.js'; import { PublicKey } from './public_key.js'; @@ -51,7 +51,10 @@ export class CompleteAddress { return new CompleteAddress(address, pubKey, partialAddress); } - static async fromPrivateKeyAndPartialAddress(privateKey: PrivateKey, partialAddress: Fr): Promise { + static async fromPrivateKeyAndPartialAddress( + privateKey: GrumpkinPrivateKey, + partialAddress: Fr, + ): Promise { const wasm = await CircuitsWasm.get(); const grumpkin = new Grumpkin(wasm); const pubKey = grumpkin.mul(Grumpkin.generator, privateKey); diff --git a/yarn-project/circuits.js/src/types/grumpkin_private_key.ts b/yarn-project/circuits.js/src/types/grumpkin_private_key.ts new file mode 100644 index 00000000000..8a394773730 --- /dev/null +++ b/yarn-project/circuits.js/src/types/grumpkin_private_key.ts @@ -0,0 +1,4 @@ +import { GrumpkinScalar } from '../index.js'; + +/** A type alias for private key which belongs to the scalar field of Grumpkin curve. */ +export type GrumpkinPrivateKey = GrumpkinScalar; diff --git a/yarn-project/circuits.js/src/types/index.ts b/yarn-project/circuits.js/src/types/index.ts index 95609ef2323..b244de25e3b 100644 --- a/yarn-project/circuits.js/src/types/index.ts +++ b/yarn-project/circuits.js/src/types/index.ts @@ -2,5 +2,5 @@ export * from './contract_function_dao.js'; export * from './complete_address.js'; export * from './deployment_info.js'; export * from './partial_address.js'; -export * from './private_key.js'; +export * from './grumpkin_private_key.js'; export * from './public_key.js'; diff --git a/yarn-project/circuits.js/src/types/private_key.test.ts b/yarn-project/circuits.js/src/types/private_key.test.ts deleted file mode 100644 index 20109d2c091..00000000000 --- a/yarn-project/circuits.js/src/types/private_key.test.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { PrivateKey } from './private_key.js'; - -describe('PrivateKey', () => { - it('throws when the key buffer is not 32 bytes long', () => { - expect(() => new PrivateKey(Buffer.alloc(0))).toThrowError(/Invalid private key length/); - }); - - it('can be created from a hex string', () => { - const key = PrivateKey.fromString('0x' + 'a'.repeat(64)); - expect(key.value).toEqual(Buffer.from('a'.repeat(64), 'hex')); - }); - - it('correctly ignores 0x prefix in hex string', () => { - const key = PrivateKey.fromString('0x' + 'a'.repeat(64)); - expect(key.value).toEqual(Buffer.from('a'.repeat(64), 'hex')); - }); -}); diff --git a/yarn-project/circuits.js/src/types/private_key.ts b/yarn-project/circuits.js/src/types/private_key.ts deleted file mode 100644 index dee05ab35f0..00000000000 --- a/yarn-project/circuits.js/src/types/private_key.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { randomBytes } from '@aztec/foundation/crypto'; - -/** - * A wrapper around a buffer representation of a private key with validation checks. - */ -export class PrivateKey { - constructor( - /** A buffer containing the private key. */ - public value: Buffer, - ) { - if (value.length != 32) { - throw new Error(`Invalid private key length. Got ${value.length}, expected 32.`); - } - } - - /** - * Converts the private key to a hex string. - * @returns A hex string representation of the private key. - */ - public toString(): string { - return this.value.toString('hex'); - } - - /** - * Creates a PrivateKey instance from a hex string. - * @param keyString - A hex string representation of the private key. - * @returns A PrivateKey instance. - */ - public static fromString(keyString: string): PrivateKey { - if (keyString.startsWith('0x')) { - keyString = keyString.slice(2); - } - if (keyString.length != 64) { - throw new Error(`Invalid private key string length. Got ${keyString.length}, expected 64.`); - } - return new PrivateKey(Buffer.from(keyString, 'hex')); - } - - /** - * Creates a random PrivateKey instance. - * @returns A PrivateKey instance. - */ - public static random(): PrivateKey { - return new PrivateKey(randomBytes(32)); - } -} diff --git a/yarn-project/end-to-end/scripts/run_tests_local b/yarn-project/end-to-end/scripts/run_tests_local index 1ea02e7bd9b..9d566e43885 100755 --- a/yarn-project/end-to-end/scripts/run_tests_local +++ b/yarn-project/end-to-end/scripts/run_tests_local @@ -10,7 +10,7 @@ aws ecr get-login-password --region us-east-2 | docker login --username AWS --pa BS=$(git rev-parse --show-toplevel)/build-system/scripts -for REPO in end-to-end; do +for REPO in aztec.js end-to-end aztec-sandbox; do docker pull $($BS/calculate_image_uri $REPO) docker tag $($BS/calculate_image_uri $REPO) aztecprotocol/$REPO:latest done diff --git a/yarn-project/end-to-end/src/e2e_account_contracts.test.ts b/yarn-project/end-to-end/src/e2e_account_contracts.test.ts index e0e179cae19..760afc1637d 100644 --- a/yarn-project/end-to-end/src/e2e_account_contracts.test.ts +++ b/yarn-project/end-to-end/src/e2e_account_contracts.test.ts @@ -12,17 +12,19 @@ import { SingleKeyAccountContract, Wallet, } from '@aztec/aztec.js'; -import { CompleteAddress, PrivateKey } from '@aztec/circuits.js'; +import { CompleteAddress, GrumpkinPrivateKey, GrumpkinScalar } from '@aztec/circuits.js'; import { toBigInt } from '@aztec/foundation/serialize'; import { ChildContract } from '@aztec/noir-contracts/types'; +import { randomBytes } from 'crypto'; + import { setup } from './fixtures/utils.js'; function itShouldBehaveLikeAnAccountContract( - getAccountContract: (encryptionKey: PrivateKey) => AccountContract, + getAccountContract: (encryptionKey: GrumpkinPrivateKey) => AccountContract, walletSetup: ( rpc: AztecRPC, - encryptionPrivateKey: PrivateKey, + encryptionPrivateKey: GrumpkinPrivateKey, accountContract: AccountContract, address?: CompleteAddress, ) => Promise<{ account: Account; wallet: Wallet }>, @@ -32,11 +34,11 @@ function itShouldBehaveLikeAnAccountContract( let child: ChildContract; let account: Account; let wallet: Wallet; - let encryptionPrivateKey: PrivateKey; + let encryptionPrivateKey: GrumpkinPrivateKey; beforeEach(async () => { context = await setup(0); - encryptionPrivateKey = PrivateKey.random(); + encryptionPrivateKey = GrumpkinScalar.random(); ({ account, wallet } = await walletSetup( context.aztecRpcServer, @@ -73,7 +75,7 @@ function itShouldBehaveLikeAnAccountContract( const { wallet: invalidWallet } = await walletSetup( context.aztecRpcServer, encryptionPrivateKey, - getAccountContract(PrivateKey.random()), + getAccountContract(GrumpkinScalar.random()), accountAddress, ); const childWithInvalidWallet = await ChildContract.at(child.address, invalidWallet); @@ -87,7 +89,7 @@ function itShouldBehaveLikeAnAccountContract( describe('e2e_account_contracts', () => { const base = async ( rpc: AztecRPC, - encryptionPrivateKey: PrivateKey, + encryptionPrivateKey: GrumpkinPrivateKey, accountContract: AccountContract, address?: CompleteAddress, ) => { @@ -98,25 +100,25 @@ describe('e2e_account_contracts', () => { describe('schnorr single-key account', () => { itShouldBehaveLikeAnAccountContract( - (encryptionKey: PrivateKey) => new SingleKeyAccountContract(encryptionKey), + (encryptionKey: GrumpkinPrivateKey) => new SingleKeyAccountContract(encryptionKey), base, ); }); describe('schnorr multi-key account', () => { - itShouldBehaveLikeAnAccountContract(() => new SchnorrAccountContract(PrivateKey.random()), base); + itShouldBehaveLikeAnAccountContract(() => new SchnorrAccountContract(GrumpkinScalar.random()), base); }); describe('ecdsa stored-key account', () => { - itShouldBehaveLikeAnAccountContract(() => new EcdsaAccountContract(PrivateKey.random()), base); + itShouldBehaveLikeAnAccountContract(() => new EcdsaAccountContract(randomBytes(32)), base); }); describe('eip single-key account', () => { itShouldBehaveLikeAnAccountContract( - (encryptionKey: PrivateKey) => new AuthWitnessAccountContract(encryptionKey), + (encryptionKey: GrumpkinPrivateKey) => new AuthWitnessAccountContract(encryptionKey), async ( rpc: AztecRPC, - encryptionPrivateKey: PrivateKey, + encryptionPrivateKey: GrumpkinPrivateKey, accountContract: AccountContract, address?: CompleteAddress, ) => { diff --git a/yarn-project/end-to-end/src/e2e_aztec_js_browser.test.ts b/yarn-project/end-to-end/src/e2e_aztec_js_browser.test.ts index da3b23a91b1..b2100c2f2ac 100644 --- a/yarn-project/end-to-end/src/e2e_aztec_js_browser.test.ts +++ b/yarn-project/end-to-end/src/e2e_aztec_js_browser.test.ts @@ -1,6 +1,6 @@ /* eslint-disable no-console */ import * as AztecJs from '@aztec/aztec.js'; -import { AztecAddress, PrivateKey } from '@aztec/circuits.js'; +import { AztecAddress, GrumpkinScalar } from '@aztec/circuits.js'; import { DebugLogger, createDebugLogger } from '@aztec/foundation/log'; import { fileURLToPath } from '@aztec/foundation/url'; import { PrivateTokenContractAbi } from '@aztec/noir-contracts/artifacts'; @@ -25,7 +25,7 @@ const PORT = 3000; const { SANDBOX_URL } = process.env; const conditionalDescribe = () => (SANDBOX_URL ? describe : describe.skip); -const privKey = PrivateKey.random(); +const privKey = GrumpkinScalar.random(); /** * This test is a bit of a special case as it's relying on sandbox and web browser and not only on anvil and node.js. @@ -110,9 +110,9 @@ conditionalDescribe()('e2e_aztec.js_browser', () => { it('Creates an account', async () => { const result = await page.evaluate( async (rpcUrl, privateKeyString) => { - const { PrivateKey, createAztecRpcClient, makeFetch, getUnsafeSchnorrAccount } = window.AztecJs; + const { GrumpkinScalar, createAztecRpcClient, makeFetch, getUnsafeSchnorrAccount } = window.AztecJs; const client = createAztecRpcClient(rpcUrl!, makeFetch([1, 2, 3], true)); - const privateKey = PrivateKey.fromString(privateKeyString); + const privateKey = GrumpkinScalar.fromString(privateKeyString); const account = getUnsafeSchnorrAccount(client, privateKey); await account.waitDeploy(); const completeAddress = await account.getCompleteAddress(); @@ -177,12 +177,13 @@ conditionalDescribe()('e2e_aztec.js_browser', () => { const deployPrivateTokenContract = async () => { const txHash = await page.evaluate( async (rpcUrl, privateKeyString, initialBalance, PrivateTokenContractAbi) => { - const { PrivateKey, DeployMethod, createAztecRpcClient, makeFetch, getUnsafeSchnorrAccount } = window.AztecJs; + const { GrumpkinScalar, DeployMethod, createAztecRpcClient, makeFetch, getUnsafeSchnorrAccount } = + window.AztecJs; const client = createAztecRpcClient(rpcUrl!, makeFetch([1, 2, 3], true)); let accounts = await client.getAccounts(); if (accounts.length === 0) { // This test needs an account for deployment. We create one in case there is none available in the RPC server. - const privateKey = PrivateKey.fromString(privateKeyString); + const privateKey = GrumpkinScalar.fromString(privateKeyString); await getUnsafeSchnorrAccount(client, privateKey).waitDeploy(); accounts = await client.getAccounts(); } diff --git a/yarn-project/end-to-end/src/e2e_cli.test.ts b/yarn-project/end-to-end/src/e2e_cli.test.ts index 9f536f7b254..5dd385ba58f 100644 --- a/yarn-project/end-to-end/src/e2e_cli.test.ts +++ b/yarn-project/end-to-end/src/e2e_cli.test.ts @@ -131,7 +131,7 @@ describe('CLI e2e test', () => { // generate a private key debug('Create an account using a private key'); await run('generate-private-key', false); - const privKey = findInLogs(/Private\sKey:\s+(?[a-fA-F0-9]+)/)?.groups?.privKey; + const privKey = findInLogs(/Private\sKey:\s+0x(?[a-fA-F0-9]+)/)?.groups?.privKey; expect(privKey).toHaveLength(64); await run(`create-account --private-key ${privKey}`); const foundAddress = findInLogs(/Address:\s+(?
0x[a-fA-F0-9]+)/)?.groups?.address; diff --git a/yarn-project/end-to-end/src/e2e_escrow_contract.test.ts b/yarn-project/end-to-end/src/e2e_escrow_contract.test.ts index 1456efa0ab3..465b720f348 100644 --- a/yarn-project/end-to-end/src/e2e_escrow_contract.test.ts +++ b/yarn-project/end-to-end/src/e2e_escrow_contract.test.ts @@ -1,7 +1,7 @@ import { AztecNodeService } from '@aztec/aztec-node'; import { AztecRPCServer } from '@aztec/aztec-rpc'; import { AztecAddress, BatchCall, Wallet, generatePublicKey } from '@aztec/aztec.js'; -import { CompleteAddress, Fr, PrivateKey, getContractDeploymentInfo } from '@aztec/circuits.js'; +import { CompleteAddress, Fr, GrumpkinPrivateKey, GrumpkinScalar, getContractDeploymentInfo } from '@aztec/circuits.js'; import { DebugLogger } from '@aztec/foundation/log'; import { EscrowContractAbi } from '@aztec/noir-contracts/artifacts'; import { EscrowContract, PrivateTokenContract } from '@aztec/noir-contracts/types'; @@ -21,7 +21,7 @@ describe('e2e_escrow_contract', () => { let owner: AztecAddress; let recipient: AztecAddress; - let escrowPrivateKey: PrivateKey; + let escrowPrivateKey: GrumpkinPrivateKey; let escrowPublicKey: PublicKey; beforeEach(async () => { @@ -32,7 +32,7 @@ describe('e2e_escrow_contract', () => { // Generate private key for escrow contract, register key in rpc server, and deploy // Note that we need to register it first if we want to emit an encrypted note for it in the constructor - escrowPrivateKey = PrivateKey.random(); + escrowPrivateKey = GrumpkinScalar.random(); escrowPublicKey = await generatePublicKey(escrowPrivateKey); const salt = Fr.random(); const deployInfo = await getContractDeploymentInfo(EscrowContractAbi, [owner], salt, escrowPublicKey); diff --git a/yarn-project/end-to-end/src/e2e_lending_contract.test.ts b/yarn-project/end-to-end/src/e2e_lending_contract.test.ts index 499b7497ac3..0be2de648ac 100644 --- a/yarn-project/end-to-end/src/e2e_lending_contract.test.ts +++ b/yarn-project/end-to-end/src/e2e_lending_contract.test.ts @@ -10,7 +10,7 @@ import { Fr, computeMessageSecretHash, } from '@aztec/aztec.js'; -import { CircuitsWasm, CompleteAddress, FunctionSelector, GeneratorIndex, PrivateKey } from '@aztec/circuits.js'; +import { CircuitsWasm, CompleteAddress, FunctionSelector, GeneratorIndex, GrumpkinScalar } from '@aztec/circuits.js'; import { pedersenPlookupCommitInputs, pedersenPlookupCompressWithHashIndex } from '@aztec/circuits.js/barretenberg'; import { DebugLogger } from '@aztec/foundation/log'; import { LendingContract, NativeTokenContract, PriceFeedContract } from '@aztec/noir-contracts/types'; @@ -82,7 +82,7 @@ describe('e2e_lending_contract', () => { beforeEach(async () => { ({ aztecNode, aztecRpcServer, logger, cheatCodes: cc } = await setup(0)); - const privateKey = PrivateKey.random(); + const privateKey = GrumpkinScalar.random(); const account = new Account(aztecRpcServer, privateKey, new AuthWitnessAccountContract(privateKey)); const entryPoint = (await account.getEntrypoint()) as unknown as AuthWitnessAccountEntrypoint; diff --git a/yarn-project/end-to-end/src/e2e_multiple_accounts_1_enc_key.test.ts b/yarn-project/end-to-end/src/e2e_multiple_accounts_1_enc_key.test.ts index 8e6a1177f1c..602c29bdffb 100644 --- a/yarn-project/end-to-end/src/e2e_multiple_accounts_1_enc_key.test.ts +++ b/yarn-project/end-to-end/src/e2e_multiple_accounts_1_enc_key.test.ts @@ -1,7 +1,7 @@ import { AztecNodeService } from '@aztec/aztec-node'; import { AztecRPCServer } from '@aztec/aztec-rpc'; import { AztecAddress, Wallet, generatePublicKey, getSchnorrAccount } from '@aztec/aztec.js'; -import { PrivateKey } from '@aztec/circuits.js'; +import { GrumpkinScalar } from '@aztec/circuits.js'; import { DebugLogger } from '@aztec/foundation/log'; import { PrivateTokenContract } from '@aztec/noir-contracts/types'; import { AztecRPC, TxStatus } from '@aztec/types'; @@ -23,11 +23,11 @@ describe('e2e_multiple_accounts_1_enc_key', () => { beforeEach(async () => { ({ aztecNode, aztecRpcServer, logger } = await setup(0)); - const encryptionPrivateKey = PrivateKey.random(); + const encryptionPrivateKey = GrumpkinScalar.random(); for (let i = 0; i < numAccounts; i++) { logger(`Deploying account contract ${i}/3...`); - const signingPrivateKey = PrivateKey.random(); + const signingPrivateKey = GrumpkinScalar.random(); const account = getSchnorrAccount(aztecRpcServer, encryptionPrivateKey, signingPrivateKey); const wallet = await account.waitDeploy({ interval: 0.1 }); const { address } = await account.getCompleteAddress(); diff --git a/yarn-project/end-to-end/src/e2e_sandbox_example.test.ts b/yarn-project/end-to-end/src/e2e_sandbox_example.test.ts index eeb564a3cea..3ab7245f3c6 100644 --- a/yarn-project/end-to-end/src/e2e_sandbox_example.test.ts +++ b/yarn-project/end-to-end/src/e2e_sandbox_example.test.ts @@ -4,7 +4,6 @@ // docs:start:imports import { AztecRPC, - PrivateKey, createAztecRpcClient, createDebugLogger, getSchnorrAccount, @@ -16,6 +15,7 @@ import { /* eslint-enable @typescript-eslint/no-unused-vars */ // Note: this is a hack to make the docs use http://localhost:8080 and CI to use the SANDBOX_URL import { createAztecRpcClient as createAztecRpcClient2 } from '@aztec/aztec.js'; +import { GrumpkinScalar } from '@aztec/circuits.js'; import { defaultFetch } from '@aztec/foundation/json-rpc/client'; import { PrivateTokenContract } from '@aztec/noir-contracts/types'; @@ -58,8 +58,8 @@ describe('e2e_sandbox_example', () => { .map(() => getSchnorrAccount( aztecRpc, - PrivateKey.random(), // encryption private key - PrivateKey.random(), // signing private key + GrumpkinScalar.random(), // encryption private key + GrumpkinScalar.random(), // signing private key ), ); return await Promise.all( diff --git a/yarn-project/end-to-end/src/fixtures/utils.ts b/yarn-project/end-to-end/src/fixtures/utils.ts index 250a09a09fb..e9d322e7025 100644 --- a/yarn-project/end-to-end/src/fixtures/utils.ts +++ b/yarn-project/end-to-end/src/fixtures/utils.ts @@ -17,10 +17,10 @@ import { getUnsafeSchnorrAccount, makeFetch, } from '@aztec/aztec.js'; -import { CompleteAddress, PrivateKey } from '@aztec/circuits.js'; +import { CompleteAddress, GrumpkinPrivateKey } from '@aztec/circuits.js'; import { DeployL1Contracts, deployL1Contract, deployL1Contracts } from '@aztec/ethereum'; import { ContractAbi } from '@aztec/foundation/abi'; -import { Fr } from '@aztec/foundation/fields'; +import { Fr, GrumpkinScalar } from '@aztec/foundation/fields'; import { DebugLogger, createDebugLogger } from '@aztec/foundation/log'; import { retryUntil } from '@aztec/foundation/retry'; import { PortalERC20Abi, PortalERC20Bytecode, TokenPortalAbi, TokenPortalBytecode } from '@aztec/l1-artifacts'; @@ -130,7 +130,7 @@ const setupL1Contracts = async (l1RpcUrl: string, account: HDAccount, logger: De export async function setupAztecRPCServer( numberOfAccounts: number, aztecNode: AztecNodeService | undefined, - firstPrivKey: PrivateKey | null = null, + firstPrivKey: GrumpkinPrivateKey | null = null, logger = getLogger(), useLogSuffix = false, ): Promise<{ @@ -162,7 +162,7 @@ export async function setupAztecRPCServer( // Prepare deployments for (let i = 0; i < numberOfAccounts; ++i) { - const privateKey = i === 0 && firstPrivKey !== null ? firstPrivKey! : PrivateKey.random(); + const privateKey = i === 0 && firstPrivKey !== null ? firstPrivKey! : GrumpkinScalar.random(); const account = getUnsafeSchnorrAccount(aztecRpcServer, privateKey); await account.getDeployMethod().then(d => d.simulate({ contractAddressSalt: account.salt })); accounts.push(account); @@ -241,16 +241,24 @@ export async function setup( const deployL1ContractsValues = await setupL1Contracts(config.rpcUrl, hdAccount, logger); const privKeyRaw = hdAccount.getHdKey().privateKey; - const privKey = privKeyRaw === null ? null : new PrivateKey(Buffer.from(privKeyRaw)); + const publisherPrivKey = privKeyRaw === null ? null : Buffer.from(privKeyRaw); + // TODO(#2052): This reduction is not secure enough. TACKLE THIS ISSUE BEFORE MAINNET. + const firstRpcAccountPrivKey = + publisherPrivKey === null ? null : GrumpkinScalar.fromBufferWithReduction(publisherPrivKey); - config.publisherPrivateKey = privKey!; + config.publisherPrivateKey = `0x${publisherPrivKey!.toString('hex')}`; config.rollupContract = deployL1ContractsValues.rollupAddress; config.contractDeploymentEmitterContract = deployL1ContractsValues.contractDeploymentEmitterAddress; config.inboxContract = deployL1ContractsValues.inboxAddress; const aztecNode = await createAztecNode(config, logger); - const { aztecRpcServer, accounts, wallet } = await setupAztecRPCServer(numberOfAccounts, aztecNode, privKey, logger); + const { aztecRpcServer, accounts, wallet } = await setupAztecRPCServer( + numberOfAccounts, + aztecNode, + firstRpcAccountPrivKey, + logger, + ); const cheatCodes = await CheatCodes.create(config.rpcUrl, aztecRpcServer!); diff --git a/yarn-project/end-to-end/src/guides/dapp_testing.test.ts b/yarn-project/end-to-end/src/guides/dapp_testing.test.ts index e65a655da32..485da984ca5 100644 --- a/yarn-project/end-to-end/src/guides/dapp_testing.test.ts +++ b/yarn-project/end-to-end/src/guides/dapp_testing.test.ts @@ -4,8 +4,8 @@ import { AztecRPC, CheatCodes, Fr, + GrumpkinScalar, L2BlockL2Logs, - PrivateKey, createAztecRpcClient, getSandboxAccountsWallets, getSchnorrAccount, @@ -27,8 +27,8 @@ describe('guides/dapp/testing', () => { // docs:start:in-proc-sandbox ({ rpcServer: rpc, stop } = await createSandbox()); // docs:end:in-proc-sandbox - owner = await getSchnorrAccount(rpc, PrivateKey.random(), PrivateKey.random()).waitDeploy(); - recipient = await getSchnorrAccount(rpc, PrivateKey.random(), PrivateKey.random()).waitDeploy(); + owner = await getSchnorrAccount(rpc, GrumpkinScalar.random(), GrumpkinScalar.random()).waitDeploy(); + recipient = await getSchnorrAccount(rpc, GrumpkinScalar.random(), GrumpkinScalar.random()).waitDeploy(); token = await PrivateTokenContract.deploy(owner, 100n, owner.getAddress()).send().deployed(); }, 30_000); @@ -62,8 +62,8 @@ describe('guides/dapp/testing', () => { beforeEach(async () => { rpc = createAztecRpcClient(SANDBOX_URL); - owner = await getSchnorrAccount(rpc, PrivateKey.random(), PrivateKey.random()).waitDeploy(); - recipient = await getSchnorrAccount(rpc, PrivateKey.random(), PrivateKey.random()).waitDeploy(); + owner = await getSchnorrAccount(rpc, GrumpkinScalar.random(), GrumpkinScalar.random()).waitDeploy(); + recipient = await getSchnorrAccount(rpc, GrumpkinScalar.random(), GrumpkinScalar.random()).waitDeploy(); token = await PrivateTokenContract.deploy(owner, 100n, owner.getAddress()).send().deployed(); }, 30_000); @@ -108,7 +108,7 @@ describe('guides/dapp/testing', () => { beforeAll(async () => { rpc = createAztecRpcClient(SANDBOX_URL); - owner = await getSchnorrAccount(rpc, PrivateKey.random(), PrivateKey.random()).waitDeploy(); + owner = await getSchnorrAccount(rpc, GrumpkinScalar.random(), GrumpkinScalar.random()).waitDeploy(); testContract = await TestContract.deploy(owner).send().deployed(); cheats = await CheatCodes.create(ETHEREUM_HOST, rpc); }, 30_000); @@ -135,8 +135,8 @@ describe('guides/dapp/testing', () => { beforeAll(async () => { rpc = createAztecRpcClient(SANDBOX_URL); - owner = await getSchnorrAccount(rpc, PrivateKey.random(), PrivateKey.random()).waitDeploy(); - recipient = await getSchnorrAccount(rpc, PrivateKey.random(), PrivateKey.random()).waitDeploy(); + owner = await getSchnorrAccount(rpc, GrumpkinScalar.random(), GrumpkinScalar.random()).waitDeploy(); + recipient = await getSchnorrAccount(rpc, GrumpkinScalar.random(), GrumpkinScalar.random()).waitDeploy(); token = await PrivateTokenContract.deploy(owner, 100n, owner.getAddress()).send().deployed(); nativeToken = await NativeTokenContract.deploy(owner, 100n, owner.getAddress()).send().deployed(); diff --git a/yarn-project/end-to-end/src/guides/writing_an_account_contract.test.ts b/yarn-project/end-to-end/src/guides/writing_an_account_contract.test.ts index a5903e5d344..cc068221806 100644 --- a/yarn-project/end-to-end/src/guides/writing_an_account_contract.test.ts +++ b/yarn-project/end-to-end/src/guides/writing_an_account_contract.test.ts @@ -11,7 +11,7 @@ import { buildTxExecutionRequest, hashPayload, } from '@aztec/aztec.js'; -import { PrivateKey } from '@aztec/circuits.js'; +import { GrumpkinPrivateKey, GrumpkinScalar } from '@aztec/circuits.js'; import { Schnorr } from '@aztec/circuits.js/barretenberg'; import { ContractAbi } from '@aztec/foundation/abi'; import { PrivateTokenContract, SchnorrHardcodedAccountContractAbi } from '@aztec/noir-contracts/types'; @@ -19,11 +19,11 @@ import { PrivateTokenContract, SchnorrHardcodedAccountContractAbi } from '@aztec import { setup } from '../fixtures/utils.js'; // docs:start:account-contract -const PRIVATE_KEY = PrivateKey.fromString('0xff2b5f8212061f0e074fc8794ffe8524130434889df20a912d7329e03894ccff'); +const PRIVATE_KEY = GrumpkinScalar.fromString('0xd35d743ac0dfe3d6dbe6be8c877cb524a00ab1e3d52d7bada095dfc8894ccfa'); /** Account contract implementation that authenticates txs using Schnorr signatures. */ class SchnorrHardcodedKeyAccountContract implements AccountContract { - constructor(private privateKey: PrivateKey = PRIVATE_KEY) {} + constructor(private privateKey: GrumpkinPrivateKey = PRIVATE_KEY) {} getContractAbi(): ContractAbi { // Return the ABI of the SchnorrHardcodedAccount contract. @@ -87,7 +87,7 @@ describe('guides/writing_an_account_contract', () => { it('works', async () => { const { aztecRpcServer: rpc, logger } = context; // docs:start:account-contract-deploy - const encryptionPrivateKey = PrivateKey.random(); + const encryptionPrivateKey = GrumpkinScalar.random(); const account = new Account(rpc, encryptionPrivateKey, new SchnorrHardcodedKeyAccountContract()); const wallet = await account.waitDeploy(); const address = wallet.getCompleteAddress().address; @@ -105,7 +105,7 @@ describe('guides/writing_an_account_contract', () => { expect(balance).toEqual(150n); // docs:start:account-contract-fails - const wrongKey = PrivateKey.random(); + const wrongKey = GrumpkinScalar.random(); const wrongAccountContract = new SchnorrHardcodedKeyAccountContract(wrongKey); const wrongAccount = new Account(rpc, encryptionPrivateKey, wrongAccountContract, wallet.getCompleteAddress()); const wrongWallet = await wrongAccount.getWallet(); diff --git a/yarn-project/end-to-end/src/integration_l1_publisher.test.ts b/yarn-project/end-to-end/src/integration_l1_publisher.test.ts index 60934255d34..43274b8acf0 100644 --- a/yarn-project/end-to-end/src/integration_l1_publisher.test.ts +++ b/yarn-project/end-to-end/src/integration_l1_publisher.test.ts @@ -8,7 +8,6 @@ import { MAX_NEW_NULLIFIERS_PER_TX, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP, - PrivateKey, PublicDataUpdateRequest, makeTuple, range, @@ -147,7 +146,7 @@ describe('L1Publisher integration', () => { rollupContract: EthAddress.fromString(rollupAddress), inboxContract: EthAddress.fromString(inboxAddress), contractDeploymentEmitterContract: EthAddress.fromString(contractDeploymentEmitterAddress), - publisherPrivateKey: PrivateKey.fromString(sequencerPK), + publisherPrivateKey: sequencerPK, l1BlockPublishRetryIntervalMS: 100, }); diff --git a/yarn-project/foundation/src/fields/grumpkin_scalar.test.ts b/yarn-project/foundation/src/fields/grumpkin_scalar.test.ts new file mode 100644 index 00000000000..bb5d7288d2d --- /dev/null +++ b/yarn-project/foundation/src/fields/grumpkin_scalar.test.ts @@ -0,0 +1,55 @@ +import { GrumpkinScalar } from './grumpkin_scalar.js'; + +describe('GrumpkinScalar Serialization', () => { + // Test case for GrumpkinScalar.fromHighLow + it('fromHighLow should serialize and deserialize correctly', () => { + const original = GrumpkinScalar.random(); + const high = original.high; + const low = original.low; + + const deserialized = GrumpkinScalar.fromHighLow(high, low); + + // Check if the deserialized instance is equal to the original + expect(deserialized).toEqual(original); + }); + + // Test case for GrumpkinScalar.fromBuffer + it('fromBuffer should serialize and deserialize correctly', () => { + const original = GrumpkinScalar.random(); + const buffer = original.toBuffer(); + const deserialized = GrumpkinScalar.fromBuffer(buffer); + + // Check if the deserialized instance is equal to the original + expect(deserialized).toEqual(original); + }); + + // Test case for GrumpkinScalar.fromString + it('fromString should serialize and deserialize correctly', () => { + const original = GrumpkinScalar.random(); + const hexString = original.toString(); + const deserialized = GrumpkinScalar.fromString(hexString); + + // Check if the deserialized instance is equal to the original + expect(deserialized).toEqual(original); + }); + + // Test case for GrumpkinScalar.toBuffer + it('toBuffer should serialize and deserialize correctly', () => { + const original = GrumpkinScalar.random(); + const buffer = original.toBuffer(); + const deserialized = GrumpkinScalar.fromBuffer(buffer); + + // Check if the deserialized instance is equal to the original + expect(deserialized).toEqual(original); + }); + + // Test case for GrumpkinScalar.toString + it('toString should serialize and deserialize correctly', () => { + const original = GrumpkinScalar.random(); + const hexString = original.toString(); + const deserialized = GrumpkinScalar.fromString(hexString); + + // Check if the deserialized instance is equal to the original + expect(deserialized).toEqual(original); + }); +}); diff --git a/yarn-project/foundation/src/fields/grumpkin_scalar.ts b/yarn-project/foundation/src/fields/grumpkin_scalar.ts new file mode 100644 index 00000000000..114c35b058e --- /dev/null +++ b/yarn-project/foundation/src/fields/grumpkin_scalar.ts @@ -0,0 +1,137 @@ +import { toBigIntBE, toBufferBE, toHex } from '../bigint-buffer/index.js'; +import { randomBytes } from '../crypto/index.js'; +import { BufferReader } from '../serialize/buffer_reader.js'; +import { Fr } from './fields.js'; + +/** + * Represents a field element in a prime finite field with modulus defined by the constant MODULUS. + * @remarks Called GrumpkinScalar because it is used to represent elements in Grumpkin's scalar field as defined in + * the Aztec Yellow Paper. + */ +export class GrumpkinScalar { + static MODULUS = 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47n; + static MAX_VALUE = GrumpkinScalar.MODULUS - 1n; + static SIZE_IN_BYTES = 32; + + // The following constants are used to split a GrumpkinScalar into two Fr elements. + private static HIGH_SHIFT = BigInt((GrumpkinScalar.SIZE_IN_BYTES / 2) * 8); + private static LOW_MASK = (1n << GrumpkinScalar.HIGH_SHIFT) - 1n; + + constructor( + /** + * The element's value as a bigint in the finite field. + */ + public readonly value: bigint, + ) { + if (value > GrumpkinScalar.MAX_VALUE) { + throw new Error(`GrumpkinScalar out of range ${value}.`); + } + } + + get low(): Fr { + return new Fr(this.value & GrumpkinScalar.LOW_MASK); + } + + get high(): Fr { + return new Fr(this.value >> GrumpkinScalar.HIGH_SHIFT); + } + + /** + * Deserialize a grumpkin scalar serialized in 2 Fr. + * @param high - The high Fr element. + * @param low - The low Fr element. + * @returns A GrumpkinScalar instance with the value of the two Fr elements. + */ + static fromHighLow(high: Fr, low: Fr): GrumpkinScalar { + return new GrumpkinScalar((high.value << GrumpkinScalar.HIGH_SHIFT) + low.value); + } + + /** + * Generates a random GrumpkinScalar. + * + * @returns A new GrumpkinScalar instance with a randomly generated value. + */ + static random() { + const r = toBigIntBE(randomBytes(64)) % GrumpkinScalar.MODULUS; + return new this(r); + } + + /** + * Create an instance of GrumpkinScalar from a given buffer or BufferReader. + * @remarks Reads SIZE_IN_BYTES from the provided buffer and converts it to a bigint, then creates a new instance + * with that value. Throws an error if the value is out of range for the calling class. + * + * @param buffer - The input buffer or BufferReader containing the bytes representing the value. + * @returns A GrumpkinScalar instance. + */ + static fromBuffer(buffer: Buffer | BufferReader) { + const reader = BufferReader.asReader(buffer); + return new this(toBigIntBE(reader.readBytes(this.SIZE_IN_BYTES))); + } + + /** + * Like fromBuffer, but reduces the value modulo MODULUS. + * + * @param buffer - The Buffer or BufferReader containing the bytes representing the value. + * @returns GrumpkinScalar with the decoded value. + */ + static fromBufferWithReduction(buffer: Buffer | BufferReader) { + const reader = BufferReader.asReader(buffer); + const value = toBigIntBE(reader.readBytes(GrumpkinScalar.SIZE_IN_BYTES)) % GrumpkinScalar.MODULUS; + return new GrumpkinScalar(value); + } + + /** + * Create a GrumpkinScalar instance from a hex-encoded string. + * The input 'address' can be either prefixed with '0x' or not, and should have exactly 64 hex characters. + * Throws an error if the input length is invalid or the address value is out of range. + * + * @param address - The hex-encoded string representing the field element. + * @returns A GrumpkinScalar instance. + */ + static fromString(address: string) { + return GrumpkinScalar.fromBuffer(Buffer.from(address.replace(/^0x/i, ''), 'hex')); + } + + /** + * Converts the bigint value of the instance to a Buffer representation. + * The output buffer has a fixed size, determined by the 'SIZE_IN_BYTES' constant. + * + * @returns A Buffer containing the byte representation of the instance's value. + */ + toBuffer() { + return toBufferBE(this.value, GrumpkinScalar.SIZE_IN_BYTES); + } + + /** + * Converts the GrumpkinScalar value to a hexadecimal string representation. + * The resulting string is prefixed with '0x' and contains the exact number of hex characters required + * to represent the numeric value of this instance. + * + * @returns A hexadecimal string representing the GrumpkinScalar value. + */ + toString() { + return toHex(this.value); + } + + /** + * Check if the value of the current instance is zero. + * This function compares the internal 'value' property with 0n (BigInt representation of zero). + * Returns true if the value is zero, otherwise returns false. + * + * @returns A boolean indicating whether the value is zero or not. + */ + isZero() { + return this.value === 0n; + } + + /** + * Converts the value of the GrumpkinScalar instance to a friendly JSON format. + * The output is a hexadecimal string representation of the value with '0x' prefix. + * + * @returns A string representing the value in the JSON format. + */ + toFriendlyJSON() { + return this.toString(); + } +} diff --git a/yarn-project/foundation/src/fields/index.ts b/yarn-project/foundation/src/fields/index.ts index aa4e441f34f..a6b24d24401 100644 --- a/yarn-project/foundation/src/fields/index.ts +++ b/yarn-project/foundation/src/fields/index.ts @@ -1,3 +1,4 @@ export * from './fields.js'; export * from './point.js'; export * from './coordinate.js'; +export * from './grumpkin_scalar.js'; diff --git a/yarn-project/foundation/src/json-rpc/convert.ts b/yarn-project/foundation/src/json-rpc/convert.ts index aec26c8f5cf..bcd5b15d3c7 100644 --- a/yarn-project/foundation/src/json-rpc/convert.ts +++ b/yarn-project/foundation/src/json-rpc/convert.ts @@ -88,7 +88,7 @@ export function convertFromJsonObj(cc: ClassConverter, obj: any): any { if (cc.isRegisteredClassName(obj.type)) { return cc.toClassObj(obj); } else { - throw new Error(`Object ${obj.type} not registered for serialisation`); + throw new Error(`Object ${obj.type} not registered for serialisation FROM JSON`); } } @@ -153,7 +153,7 @@ export function convertToJsonObj(cc: ClassConverter, obj: any): any { return newObj; } else { // Throw if this is a non-primitive class that was not registered - throw new Error(`Object ${obj.constructor.name} not registered for serialisation`); + throw new Error(`Object ${obj.constructor.name} not registered for serialisation TO JSON`); } } diff --git a/yarn-project/key-store/src/key_pair.ts b/yarn-project/key-store/src/key_pair.ts index 2a27127707f..ac65dac2104 100644 --- a/yarn-project/key-store/src/key_pair.ts +++ b/yarn-project/key-store/src/key_pair.ts @@ -1,9 +1,12 @@ -import { PrivateKey } from '@aztec/circuits.js'; +import { GrumpkinPrivateKey, GrumpkinScalar } from '@aztec/circuits.js'; import { Grumpkin } from '@aztec/circuits.js/barretenberg'; import { KeyPair, PublicKey } from '@aztec/types'; /** - * The ConstantKeyPair class is an implementation of the KeyPair interface, which allows generation and management of a constant public and private key pair. It provides methods for creating a random instance of the key pair, retrieving the public key, getting the private key. This class ensures the persistence and consistency of the generated keys, making it suitable for cryptographic operations where constant key pairs are required. + * The ConstantKeyPair class is an implementation of the KeyPair interface, which allows generation and management of + * a constant public and private key pair. It provides methods for creating a random instance of the key pair, + * retrieving the public key, getting the private key. This class ensures the persistence and consistency of + * the generated keys, making it suitable for cryptographic operations where constant key pairs are required. */ export class ConstantKeyPair implements KeyPair { /** @@ -16,7 +19,7 @@ export class ConstantKeyPair implements KeyPair { * @returns A randomly generated ConstantKeyPair instance. */ public static random(curve: Grumpkin) { - const privateKey = PrivateKey.random(); + const privateKey = GrumpkinScalar.random(); const publicKey = curve.mul(curve.generator(), privateKey); return new ConstantKeyPair(publicKey, privateKey); } @@ -28,12 +31,12 @@ export class ConstantKeyPair implements KeyPair { * @param privateKey - The private key. * @returns A new instance. */ - public static fromPrivateKey(curve: Grumpkin, privateKey: PrivateKey) { + public static fromPrivateKey(curve: Grumpkin, privateKey: GrumpkinPrivateKey) { const publicKey = curve.mul(curve.generator(), privateKey); return new ConstantKeyPair(publicKey, privateKey); } - constructor(private publicKey: PublicKey, private privateKey: PrivateKey) {} + constructor(private publicKey: PublicKey, private privateKey: GrumpkinPrivateKey) {} public getPublicKey(): PublicKey { return this.publicKey; diff --git a/yarn-project/key-store/src/test_key_store.ts b/yarn-project/key-store/src/test_key_store.ts index cea6fc3a3b8..680f5b98833 100644 --- a/yarn-project/key-store/src/test_key_store.ts +++ b/yarn-project/key-store/src/test_key_store.ts @@ -1,4 +1,4 @@ -import { PrivateKey } from '@aztec/circuits.js'; +import { GrumpkinPrivateKey } from '@aztec/circuits.js'; import { Grumpkin } from '@aztec/circuits.js/barretenberg'; import { KeyPair, KeyStore, PublicKey } from '@aztec/types'; @@ -12,7 +12,7 @@ export class TestKeyStore implements KeyStore { private accounts: KeyPair[] = []; constructor(private curve: Grumpkin) {} - public addAccount(privKey: PrivateKey): PublicKey { + public addAccount(privKey: GrumpkinPrivateKey): PublicKey { const keyPair = ConstantKeyPair.fromPrivateKey(this.curve, privKey); // check if private key has already been used @@ -35,7 +35,7 @@ export class TestKeyStore implements KeyStore { return Promise.resolve(this.accounts.map(a => a.getPublicKey())); } - public getAccountPrivateKey(pubKey: PublicKey): Promise { + public getAccountPrivateKey(pubKey: PublicKey): Promise { const account = this.getAccount(pubKey); return account.getPrivateKey(); } diff --git a/yarn-project/noir-contracts/src/contracts/docs_example_contract/src/types/card_note.nr b/yarn-project/noir-contracts/src/contracts/docs_example_contract/src/types/card_note.nr index 9d999c8aa7c..f5b526cb0d7 100644 --- a/yarn-project/noir-contracts/src/contracts/docs_example_contract/src/types/card_note.nr +++ b/yarn-project/noir-contracts/src/contracts/docs_example_contract/src/types/card_note.nr @@ -54,7 +54,8 @@ impl CardNote { let secret = get_secret_key(self.owner); dep::std::hash::pedersen([ note_hash_for_nullify, - secret, + secret.high, + secret.low, ])[0] } diff --git a/yarn-project/noir-contracts/src/contracts/ecdsa_account_contract/src/ecdsa_public_key_note.nr b/yarn-project/noir-contracts/src/contracts/ecdsa_account_contract/src/ecdsa_public_key_note.nr index a53d9a443de..c8081b918f2 100644 --- a/yarn-project/noir-contracts/src/contracts/ecdsa_account_contract/src/ecdsa_public_key_note.nr +++ b/yarn-project/noir-contracts/src/contracts/ecdsa_account_contract/src/ecdsa_public_key_note.nr @@ -57,7 +57,8 @@ impl EcdsaPublicKeyNote { // TODO(#1205) Should use a non-zero generator index. dep::std::hash::pedersen([ unique_siloed_note_hash, - secret, + secret.high, + secret.low, ])[0] } diff --git a/yarn-project/noir-contracts/src/contracts/escrow_contract/src/address_note.nr b/yarn-project/noir-contracts/src/contracts/escrow_contract/src/address_note.nr index c1615d54012..26752487909 100644 --- a/yarn-project/noir-contracts/src/contracts/escrow_contract/src/address_note.nr +++ b/yarn-project/noir-contracts/src/contracts/escrow_contract/src/address_note.nr @@ -32,7 +32,8 @@ impl AddressNote { // TODO(#1205) Should use a non-zero generator index. dep::std::hash::pedersen([ siloed_note_hash, - secret, + secret.high, + secret.low, ])[0] } diff --git a/yarn-project/noir-contracts/src/contracts/pokeable_token_contract/src/address_note.nr b/yarn-project/noir-contracts/src/contracts/pokeable_token_contract/src/address_note.nr index 37a2270ad32..64162d934f6 100644 --- a/yarn-project/noir-contracts/src/contracts/pokeable_token_contract/src/address_note.nr +++ b/yarn-project/noir-contracts/src/contracts/pokeable_token_contract/src/address_note.nr @@ -31,7 +31,8 @@ impl AddressNote { // TODO(#1205) Should use a non-zero generator index. dep::std::hash::pedersen([ unique_siloed_note_hash, - secret, + secret.high, + secret.low, ])[0] } diff --git a/yarn-project/noir-contracts/src/contracts/schnorr_account_contract/src/public_key_note.nr b/yarn-project/noir-contracts/src/contracts/schnorr_account_contract/src/public_key_note.nr index f42d5e7ded3..53abc3b4f58 100644 --- a/yarn-project/noir-contracts/src/contracts/schnorr_account_contract/src/public_key_note.nr +++ b/yarn-project/noir-contracts/src/contracts/schnorr_account_contract/src/public_key_note.nr @@ -36,7 +36,8 @@ impl PublicKeyNote { // TODO(#1205) Should use a non-zero generator index. dep::std::hash::pedersen([ unique_siloed_note_hash, - secret, + secret.high, + secret.low, ])[0] } diff --git a/yarn-project/noir-contracts/src/contracts/schnorr_hardcoded_account_contract/src/main.nr b/yarn-project/noir-contracts/src/contracts/schnorr_hardcoded_account_contract/src/main.nr index 1f07c60ad1f..002b00df407 100644 --- a/yarn-project/noir-contracts/src/contracts/schnorr_hardcoded_account_contract/src/main.nr +++ b/yarn-project/noir-contracts/src/contracts/schnorr_hardcoded_account_contract/src/main.nr @@ -1,8 +1,8 @@ // docs:start:contract // Account contract that uses Schnorr signatures for authentication using a hardcoded public key. contract SchnorrHardcodedAccount { - global public_key_x: Field = 0x077a724f70dfb200eae8951b27aebb5c97629eb03224b397b109d09509f978a4; - global public_key_y: Field = 0x0f0aad1ece7d55d177d4b44fd28f53bfdc0978be15939ce8762f71db88f37774; + global public_key_x: Field = 0x0ede3d33c920df8fdf43f3e39ed38b0882c25b056620ef52fd016fe811aa2443; + global public_key_y: Field = 0x29155934ffaa105323695b5f91faadd84acc21f4a8bda2fad760f992d692bc7f; use dep::std; use dep::aztec::{ diff --git a/yarn-project/noir-libs/noir-aztec/src/oracle/get_secret_key.nr b/yarn-project/noir-libs/noir-aztec/src/oracle/get_secret_key.nr index b88d410665d..87f36f61920 100644 --- a/yarn-project/noir-libs/noir-aztec/src/oracle/get_secret_key.nr +++ b/yarn-project/noir-libs/noir-aztec/src/oracle/get_secret_key.nr @@ -1,10 +1,17 @@ -use crate::types::point::Point; +use crate::types::{ + point::Point, + grumpkin_scalar::{ + GRUMPKIN_SCALAR_SERIALISED_LEN, + GrumpkinScalar, + deserialise_grumpkin_scalar, + }, +}; use crate::oracle::get_public_key::get_public_key; #[oracle(getSecretKey)] -fn get_secret_key_oracle(_owner: Point) -> Field {} +fn get_secret_key_oracle(_owner: Point) -> [Field; GRUMPKIN_SCALAR_SERIALISED_LEN] {} -unconstrained fn get_secret_key(owner: Field) -> Field { +unconstrained fn get_secret_key(owner: Field) -> GrumpkinScalar { let owner_nullifying_public_key = get_public_key(owner); - get_secret_key_oracle(owner_nullifying_public_key) + deserialise_grumpkin_scalar(get_secret_key_oracle(owner_nullifying_public_key)) } \ No newline at end of file diff --git a/yarn-project/noir-libs/noir-aztec/src/types.nr b/yarn-project/noir-libs/noir-aztec/src/types.nr index 81b7155d402..8c3255571f0 100644 --- a/yarn-project/noir-libs/noir-aztec/src/types.nr +++ b/yarn-project/noir-libs/noir-aztec/src/types.nr @@ -1,3 +1,4 @@ +mod grumpkin_scalar; mod point; mod vec; // This can/should be moved out into an official noir library mod type_serialisation; \ No newline at end of file diff --git a/yarn-project/noir-libs/noir-aztec/src/types/grumpkin_scalar.nr b/yarn-project/noir-libs/noir-aztec/src/types/grumpkin_scalar.nr new file mode 100644 index 00000000000..00b0041b8e3 --- /dev/null +++ b/yarn-project/noir-libs/noir-aztec/src/types/grumpkin_scalar.nr @@ -0,0 +1,31 @@ +use crate::types::type_serialisation::TypeSerialisationInterface; + +struct GrumpkinScalar { + high: Field, + low: Field, +} + +impl GrumpkinScalar { + fn new(high: Field, low: Field) -> Self { + // TODO: max value check + GrumpkinScalar { high, low } + } +} + +global GRUMPKIN_SCALAR_SERIALISED_LEN: Field = 2; + +fn deserialise_grumpkin_scalar(fields: [Field; GRUMPKIN_SCALAR_SERIALISED_LEN]) -> GrumpkinScalar { + GrumpkinScalar { + high: fields[0], + low: fields[1], + } +} + +fn serialise_grumpkin_scalar(scalar: GrumpkinScalar) -> [Field; GRUMPKIN_SCALAR_SERIALISED_LEN] { + [scalar.high, scalar.low] +} + +global GrumpkinScalarSerialisationMethods = TypeSerialisationInterface { + deserialise: deserialise_grumpkin_scalar, + serialise: serialise_grumpkin_scalar, +}; \ No newline at end of file diff --git a/yarn-project/noir-libs/value-note/src/value_note.nr b/yarn-project/noir-libs/value-note/src/value_note.nr index b4b79c1bceb..8f722d901a6 100644 --- a/yarn-project/noir-libs/value-note/src/value_note.nr +++ b/yarn-project/noir-libs/value-note/src/value_note.nr @@ -61,7 +61,8 @@ impl ValueNote { // TODO(#1205) Should use a non-zero generator index. dep::std::hash::pedersen([ note_hash_for_nullify, - secret, + secret.high, + secret.low, ])[0] } diff --git a/yarn-project/sequencer-client/src/config.ts b/yarn-project/sequencer-client/src/config.ts index 3df5613dc81..9060a659c26 100644 --- a/yarn-project/sequencer-client/src/config.ts +++ b/yarn-project/sequencer-client/src/config.ts @@ -1,4 +1,3 @@ -import { PrivateKey } from '@aztec/circuits.js'; import { EthAddress } from '@aztec/foundation/eth-address'; import { GlobalReaderConfig } from './global_variable_builder/index.js'; @@ -30,6 +29,12 @@ export function getConfigEnvVars(): SequencerClientConfig { CONTRACT_DEPLOYMENT_EMITTER_ADDRESS, } = process.env; + const publisherPrivateKey: `0x${string}` = `0x${ + SEQ_PUBLISHER_PRIVATE_KEY + ? SEQ_PUBLISHER_PRIVATE_KEY.replace('0x', '') + : '0000000000000000000000000000000000000000000000000000000000000000' + }`; + return { rpcUrl: ETHEREUM_HOST ? ETHEREUM_HOST : '', chainId: CHAIN_ID ? +CHAIN_ID : 31337, // 31337 is the default chain id for anvil @@ -43,9 +48,7 @@ export function getConfigEnvVars(): SequencerClientConfig { contractDeploymentEmitterContract: CONTRACT_DEPLOYMENT_EMITTER_ADDRESS ? EthAddress.fromString(CONTRACT_DEPLOYMENT_EMITTER_ADDRESS) : EthAddress.ZERO, - publisherPrivateKey: SEQ_PUBLISHER_PRIVATE_KEY - ? PrivateKey.fromString(SEQ_PUBLISHER_PRIVATE_KEY) - : new PrivateKey(Buffer.alloc(32)), + publisherPrivateKey, maxTxsPerBlock: SEQ_MAX_TX_PER_BLOCK ? +SEQ_MAX_TX_PER_BLOCK : 32, minTxsPerBlock: SEQ_MIN_TX_PER_BLOCK ? +SEQ_MIN_TX_PER_BLOCK : 1, }; diff --git a/yarn-project/sequencer-client/src/publisher/config.ts b/yarn-project/sequencer-client/src/publisher/config.ts index 587faf1d157..5ec4cfde76c 100644 --- a/yarn-project/sequencer-client/src/publisher/config.ts +++ b/yarn-project/sequencer-client/src/publisher/config.ts @@ -1,4 +1,3 @@ -import { PrivateKey } from '@aztec/circuits.js'; import { L1Addresses } from '@aztec/types'; /** @@ -8,7 +7,7 @@ export interface TxSenderConfig extends L1Addresses { /** * The private key to be used by the publisher. */ - publisherPrivateKey: PrivateKey; + publisherPrivateKey: `0x${string}`; /** * The RPC Url of the ethereum host. diff --git a/yarn-project/sequencer-client/src/publisher/viem-tx-sender.ts b/yarn-project/sequencer-client/src/publisher/viem-tx-sender.ts index 81d0e5ff90f..f5c1be30b53 100644 --- a/yarn-project/sequencer-client/src/publisher/viem-tx-sender.ts +++ b/yarn-project/sequencer-client/src/publisher/viem-tx-sender.ts @@ -49,7 +49,7 @@ export class ViemTxSender implements L1PublisherTxSender { contractDeploymentEmitterContract: contractDeploymentEmitterContractAddress, } = config; const chain = createEthereumChain(rpcUrl, apiKey); - this.account = privateKeyToAccount(`0x${publisherPrivateKey.toString()}`); + this.account = privateKeyToAccount(publisherPrivateKey); const walletClient = createWalletClient({ account: this.account, chain: chain.chainInfo, diff --git a/yarn-project/types/src/interfaces/aztec_rpc.ts b/yarn-project/types/src/interfaces/aztec_rpc.ts index 5e967e0cbb5..3965e5dc601 100644 --- a/yarn-project/types/src/interfaces/aztec_rpc.ts +++ b/yarn-project/types/src/interfaces/aztec_rpc.ts @@ -1,4 +1,4 @@ -import { AztecAddress, EthAddress, Fr, PartialAddress, PrivateKey } from '@aztec/circuits.js'; +import { AztecAddress, EthAddress, Fr, GrumpkinPrivateKey, PartialAddress } from '@aztec/circuits.js'; import { ContractAbi } from '@aztec/foundation/abi'; import { CompleteAddress, @@ -84,7 +84,7 @@ export interface AztecRPC { * @returns Empty promise. * @throws If the account is already registered. */ - registerAccount(privKey: PrivateKey, partialAddress: PartialAddress): Promise; + registerAccount(privKey: GrumpkinPrivateKey, partialAddress: PartialAddress): Promise; /** * Registers recipient in the Aztec RPC server. diff --git a/yarn-project/types/src/keys/key_pair.ts b/yarn-project/types/src/keys/key_pair.ts index 63c8994ff14..d8b43186049 100644 --- a/yarn-project/types/src/keys/key_pair.ts +++ b/yarn-project/types/src/keys/key_pair.ts @@ -1,4 +1,4 @@ -import { PrivateKey, PublicKey } from '@aztec/circuits.js'; +import { GrumpkinPrivateKey, PublicKey } from '@aztec/circuits.js'; /** * Represents a cryptographic public-private key pair. @@ -16,5 +16,5 @@ export interface KeyPair { * The function returns a Promise that resolves to a Buffer containing the private key. * @returns A Promise that resolves to a Buffer containing the private key. */ - getPrivateKey(): Promise; + getPrivateKey(): Promise; } diff --git a/yarn-project/types/src/keys/key_store.ts b/yarn-project/types/src/keys/key_store.ts index f39c43b4ae8..bce41ab0163 100644 --- a/yarn-project/types/src/keys/key_store.ts +++ b/yarn-project/types/src/keys/key_store.ts @@ -1,4 +1,4 @@ -import { PrivateKey, PublicKey } from '@aztec/circuits.js'; +import { GrumpkinPrivateKey, PublicKey } from '@aztec/circuits.js'; /** * Represents a secure storage for managing keys. @@ -18,7 +18,7 @@ export interface KeyStore { * @param privKey - The private key of the account. * @returns - The account's public key. */ - addAccount(privKey: PrivateKey): PublicKey; + addAccount(privKey: GrumpkinPrivateKey): PublicKey; /** * Retrieves the public keys of all accounts stored. @@ -35,5 +35,5 @@ export interface KeyStore { * @returns A Promise that resolves to a Buffer containing the private key. * @deprecated We should not require a keystore to expose private keys in plain. */ - getAccountPrivateKey(pubKey: PublicKey): Promise; + getAccountPrivateKey(pubKey: PublicKey): Promise; } diff --git a/yarn-project/types/src/logs/note_spending_info/encrypt_buffer.test.ts b/yarn-project/types/src/logs/note_spending_info/encrypt_buffer.test.ts index d81ef936460..2d79f54489a 100644 --- a/yarn-project/types/src/logs/note_spending_info/encrypt_buffer.test.ts +++ b/yarn-project/types/src/logs/note_spending_info/encrypt_buffer.test.ts @@ -1,4 +1,4 @@ -import { CircuitsWasm, PrivateKey } from '@aztec/circuits.js'; +import { CircuitsWasm, GrumpkinScalar } from '@aztec/circuits.js'; import { Grumpkin } from '@aztec/circuits.js/barretenberg'; import { randomBytes } from '@aztec/foundation/crypto'; @@ -12,9 +12,9 @@ describe('encrypt buffer', () => { }); it('derive shared secret', () => { - const ownerPrivKey = PrivateKey.random(); + const ownerPrivKey = GrumpkinScalar.random(); const ownerPubKey = grumpkin.mul(Grumpkin.generator, ownerPrivKey); - const ephPrivKey = PrivateKey.random(); + const ephPrivKey = GrumpkinScalar.random(); const ephPubKey = grumpkin.mul(Grumpkin.generator, ephPrivKey); const secretBySender = deriveAESSecret(ownerPubKey, ephPrivKey, grumpkin); @@ -24,9 +24,9 @@ describe('encrypt buffer', () => { it('convert to and from encrypted buffer', () => { const data = randomBytes(253); - const ownerPrivKey = PrivateKey.random(); + const ownerPrivKey = GrumpkinScalar.random(); const ownerPubKey = grumpkin.mul(Grumpkin.generator, ownerPrivKey); - const ephPrivKey = PrivateKey.random(); + const ephPrivKey = GrumpkinScalar.random(); const encrypted = encryptBuffer(data, ownerPubKey, ephPrivKey, grumpkin); const decrypted = decryptBuffer(encrypted, ownerPrivKey, grumpkin); expect(decrypted).not.toBeUndefined(); @@ -35,8 +35,8 @@ describe('encrypt buffer', () => { it('decrypting gibberish returns undefined', () => { const data = randomBytes(253); - const ownerPrivKey = PrivateKey.random(); - const ephPrivKey = PrivateKey.random(); + const ownerPrivKey = GrumpkinScalar.random(); + const ephPrivKey = GrumpkinScalar.random(); const ownerPubKey = grumpkin.mul(Grumpkin.generator, ownerPrivKey); const encrypted = encryptBuffer(data, ownerPubKey, ephPrivKey, grumpkin); diff --git a/yarn-project/types/src/logs/note_spending_info/encrypt_buffer.ts b/yarn-project/types/src/logs/note_spending_info/encrypt_buffer.ts index 9608bbfe320..8883ff8941e 100644 --- a/yarn-project/types/src/logs/note_spending_info/encrypt_buffer.ts +++ b/yarn-project/types/src/logs/note_spending_info/encrypt_buffer.ts @@ -1,4 +1,4 @@ -import { PrivateKey, PublicKey } from '@aztec/circuits.js'; +import { GrumpkinPrivateKey, PublicKey } from '@aztec/circuits.js'; import { Grumpkin } from '@aztec/circuits.js/barretenberg'; import { sha256 } from '@aztec/foundation/crypto'; import { Point } from '@aztec/foundation/fields'; @@ -17,7 +17,7 @@ import { createCipheriv, createDecipheriv } from 'browserify-cipher'; * @param grumpkin - The curve to use for curve operations. * @returns A Buffer containing the derived AES secret key. */ -export function deriveAESSecret(ecdhPubKey: PublicKey, ecdhPrivKey: PrivateKey, curve: Grumpkin): Buffer { +export function deriveAESSecret(ecdhPubKey: PublicKey, ecdhPrivKey: GrumpkinPrivateKey, curve: Grumpkin): Buffer { const sharedSecret = curve.mul(ecdhPubKey, ecdhPrivKey); const secretBuffer = Buffer.concat([sharedSecret.toBuffer(), numToUInt8(1)]); const hash = sha256(secretBuffer); @@ -36,7 +36,12 @@ export function deriveAESSecret(ecdhPubKey: PublicKey, ecdhPrivKey: PrivateKey, * @param curve - The curve instance used for elliptic curve operations. * @returns A Buffer containing the encrypted data and the ephemeral public key. */ -export function encryptBuffer(data: Buffer, ownerPubKey: PublicKey, ephPrivKey: PrivateKey, curve: Grumpkin): Buffer { +export function encryptBuffer( + data: Buffer, + ownerPubKey: PublicKey, + ephPrivKey: GrumpkinPrivateKey, + curve: Grumpkin, +): Buffer { const aesSecret = deriveAESSecret(ownerPubKey, ephPrivKey, curve); const aesKey = aesSecret.subarray(0, 16); const iv = aesSecret.subarray(16, 32); @@ -57,7 +62,7 @@ export function encryptBuffer(data: Buffer, ownerPubKey: PublicKey, ephPrivKey: * @param curve - The curve object used in the decryption process. * @returns The decrypted plaintext as a Buffer or undefined if decryption fails. */ -export function decryptBuffer(data: Buffer, ownerPrivKey: PrivateKey, curve: Grumpkin): Buffer | undefined { +export function decryptBuffer(data: Buffer, ownerPrivKey: GrumpkinPrivateKey, curve: Grumpkin): Buffer | undefined { const ephPubKey = Point.fromBuffer(data.subarray(-64)); const aesSecret = deriveAESSecret(ephPubKey, ownerPrivKey, curve); const aesKey = aesSecret.subarray(0, 16); diff --git a/yarn-project/types/src/logs/note_spending_info/note_spending_info.test.ts b/yarn-project/types/src/logs/note_spending_info/note_spending_info.test.ts index 55cac4ac5bf..9dac462c946 100644 --- a/yarn-project/types/src/logs/note_spending_info/note_spending_info.test.ts +++ b/yarn-project/types/src/logs/note_spending_info/note_spending_info.test.ts @@ -1,6 +1,6 @@ -import { CircuitsWasm, PrivateKey } from '@aztec/circuits.js'; +import { CircuitsWasm } from '@aztec/circuits.js'; import { Grumpkin } from '@aztec/circuits.js/barretenberg'; -import { Point } from '@aztec/foundation/fields'; +import { GrumpkinScalar, Point } from '@aztec/foundation/fields'; import { NoteSpendingInfo } from './note_spending_info.js'; @@ -19,7 +19,7 @@ describe('note_spending_info', () => { it('convert to and from encrypted buffer', () => { const noteSpendingInfo = NoteSpendingInfo.random(); - const ownerPrivKey = PrivateKey.random(); + const ownerPrivKey = GrumpkinScalar.random(); const ownerPubKey = grumpkin.mul(Grumpkin.generator, ownerPrivKey); const encrypted = noteSpendingInfo.toEncryptedBuffer(ownerPubKey, grumpkin); const decrypted = NoteSpendingInfo.fromEncryptedBuffer(encrypted, ownerPrivKey, grumpkin); @@ -31,7 +31,7 @@ describe('note_spending_info', () => { const noteSpendingInfo = NoteSpendingInfo.random(); const ownerPubKey = Point.random(); const encrypted = noteSpendingInfo.toEncryptedBuffer(ownerPubKey, grumpkin); - const randomPrivKey = PrivateKey.random(); + const randomPrivKey = GrumpkinScalar.random(); const decrypted = NoteSpendingInfo.fromEncryptedBuffer(encrypted, randomPrivKey, grumpkin); expect(decrypted).toBeUndefined(); }); diff --git a/yarn-project/types/src/logs/note_spending_info/note_spending_info.ts b/yarn-project/types/src/logs/note_spending_info/note_spending_info.ts index 314e7a8fa39..e45c25562d8 100644 --- a/yarn-project/types/src/logs/note_spending_info/note_spending_info.ts +++ b/yarn-project/types/src/logs/note_spending_info/note_spending_info.ts @@ -1,7 +1,7 @@ -import { AztecAddress, PrivateKey, PublicKey } from '@aztec/circuits.js'; +import { AztecAddress, GrumpkinPrivateKey, PublicKey } from '@aztec/circuits.js'; import { Grumpkin } from '@aztec/circuits.js/barretenberg'; import { serializeToBuffer } from '@aztec/circuits.js/utils'; -import { Fr } from '@aztec/foundation/fields'; +import { Fr, GrumpkinScalar } from '@aztec/foundation/fields'; import { BufferReader } from '@aztec/foundation/serialize'; import { decryptBuffer, encryptBuffer } from './encrypt_buffer.js'; @@ -52,7 +52,7 @@ export class NoteSpendingInfo { * @returns The encrypted NoteSpendingInfo object. */ public toEncryptedBuffer(ownerPubKey: PublicKey, curve: Grumpkin): Buffer { - const ephPrivKey = PrivateKey.random(); + const ephPrivKey: GrumpkinPrivateKey = GrumpkinScalar.random(); return encryptBuffer(this.toBuffer(), ownerPubKey, ephPrivKey, curve); } @@ -63,7 +63,11 @@ export class NoteSpendingInfo { * @param curve - The curve instance to use. * @returns Instance of NoteSpendingInfo if the decryption was successful, undefined otherwise. */ - static fromEncryptedBuffer(data: Buffer, ownerPrivKey: PrivateKey, curve: Grumpkin): NoteSpendingInfo | undefined { + static fromEncryptedBuffer( + data: Buffer, + ownerPrivKey: GrumpkinPrivateKey, + curve: Grumpkin, + ): NoteSpendingInfo | undefined { const buf = decryptBuffer(data, ownerPrivKey, curve); if (!buf) { return;