multifactor.sol
Overview
The Multifactor smart contract implements a multi-factor authentication system for secure transaction management and key control. It integrates zero-knowledge proof (ZKP) factors, JSON Web Key (JWK) management, and security card functionality to protect and authorize transfers of cryptocurrency and token exchanges. The contract supports adding, deleting, and validating cryptographic factors, managing queued transactions requiring multiple confirmations, and updating recovery and ownership keys with robust signature verification and expiration control.
This contract is designed to operate with cryptographic proofs and external validation (e.g., TLS checks) via WebAssembly modules, enforcing strong security practices to prevent unauthorized operations. It provides mechanisms to maintain and clean expired keys and transactions, ensuring the system remains efficient and secure over time.
Data Structures
Transaction
Represents a queued transaction awaiting confirmation.
Field | Type | Description |
|---|---|---|
|
| Unique transaction identifier. |
|
| Ephemeral public key (Epk) of the transaction creator. |
|
| Destination address of the transfer. |
|
| Amount of nanograms to transfer. |
|
| Mapping of ECC token amounts to transfer. |
|
| Flags controlling message sending behavior. |
|
| Payload for the internal message body. |
|
| Bounce flag for outbound message header. |
JWKData
Stores JSON Web Key modulus data with expiration.
Field | Type | Description |
|---|---|---|
|
| Modulus bytes of the JWK key. |
|
| Expiration timestamp for the modulus. |
Constants
Key contract constants include:
Versioning (
version = "1.0.1").WASM module and function identifiers used for TLS checks.
Limits on queued requests, expiration times for ephemeral keys (EPK) and JWKs.
Maximum number of security cards and factors.
Flags for message sending according to TVM specification.
State Variables
_factors_ordered_by_timestamp: Maps a composite key (expiration timestamp and EPK bits) to ephemeral public keys. Enables ordered storage and lookup of ZKP factors.
_factors_len: Number of active ZKP factors._owner_pubkey: Owner's public key serving as the master seed phrase.
_candidate_new_owner_pubkey_and_expiration: Optional candidate for ownership transfer with expiration.
_pub_recovery_key: Public key used for recovery purposes._jwk_update_key: Public key authorized for JWK updates._root_provider_certificates: Mapping of root provider certificate serial numbers to their certificate bytes.
_jwk_modulus_data: Mapping of hashed JWK key IDs to
JWKData._jwk_modulus_data_len: Number of active JWK modulus entries.
_start_point_jwk: Optional iterator starting point for cleaning expired JWKs._zkid, _index_mod_4,_iss_base_64,_lv_provider_bytes: Strings and bytes related to identity provider and verification context._use_security_card: Flag indicating if security cards are active._m_security_cards: Mapping of security card public keys to boolean flags._m_security_cards_len: Number of added security cards._m_transactions: Mapping from transaction IDs to queued
Transactionstructs._m_transactions_len: Number of pending transactions.
_min_value: Minimum allowed transaction value._max_cleanup_txns: Maximum number of expired transactions to clean in one pass.
_force_remove_oldest: Flag to force removal of oldest ZKP factors when max reached._verification_key_index: Index used in ZKP verification.
Constructor
Initializes the contract with trusted parameters, verifying all input keys and cryptographic proofs with strict expiration and non-repetition checks. It sets the initial ZKP factor, JWK modulus, root provider certificates, and relevant identity strings.
Parameters:
zkid(string): Identifier for the identity provider.proof(bytes): Zero-knowledge proof validating initial setup.epk(uint256): Ephemeral public key.epk_sig(bytes): Signature for the ephemeral public key.epk_expire_at(uint64): Expiration timestamp for epk.jwk_modulus(bytes): JWK modulus bytes.kid(bytes): Key Identifier for JWK.jwk_modulus_expire_at (
uint64): Expiration timestamp for JWK modulus.index_mod_4(uint8): Index used in cryptographic hashing.iss_base_64(string): Issuer string in base64 encoding.provider(string): Identity provider name.header_base_64(string): Header string in base64 encoding.pub_recovery_key(uint256): Public recovery key.pub_recovery_key_sig(bytes): Signature for recovery key.jwk_update_key(uint256): Public key for JWK updates.jwk_update_key_sig(bytes): Signature for JWK update key.value(uint64): Initial value parameter (used internally).root_provider_certificates(mapping(uint256 => bytes)): Initial root provider certificates.
Usage example:
Multifactor multifactor = new Multifactor(
"zkid_example",
proof_bytes,
epk,
epk_signature,
epk_expiration,
jwk_modulus_bytes,
kid_bytes,
jwk_expiration,
index_mod_4,
iss_base64_str,
"provider_name",
header_base64_str,
pub_recovery_key,
pub_recovery_key_signature,
jwk_update_key,
jwk_update_key_signature,
initial_value,
root_provider_certificates_mapping
);
Key Functions
JWK Management
addJwkModulus
Adds a new JWK modulus entry after validating the TLS data with an external WASM module. Requires ownership via the_jwk_update_key. Cleans expired entries before insertion.
Parameters:root_cert_sn (uint256): Root certificate serial number.lv_kid (bytes): Key Identifier.tls_data (bytes): TLS-related data for validation.
Returns:boolindicating success.
Errors: Throws on certificate not found, invalid TLS data, or invalid JWK.
deleteJwkModulusByUpdateJwkKey
Deletes a JWK modulus entry by itskid. Requires_jwk_update_keyownership.
Parameters:kid (bytes)cleanExpiredJwks
Internal helper that iterates through JWK entries and removes expired ones.cleanAllExpiredJwks
Public function to remove all expired JWKs, authorized by a valid ZKP factor.deleteJwkModulusByFactor
Deletes a JWK modulus entry by a factor's ephemeral key and kid, authorized by the factor.
ZKP Factor Management
addZKPfactor
Adds a new zero-knowledge proof factor after validation of signatures and proof. Cleans expired factors and optionally removes the oldest if forced. Ensures no duplicate factors.
Parameters:proof (bytes): Cryptographic proof.epk (uint256): Ephemeral public key.kid (bytes): Key Identifier.header_base_64 (string): Header string for validation.epk_expire_at (uint64): Expiration timestamp.
Returns:boolsuccess indicator.
deleteZKPfactorByItself
Allows a factor to delete itself by providing its expiration timestamp.cleanExpiredZKPFactors
Internal function to remove expired ZKP factors limited by iteration count.cleanOldestZKPFactor
Internal function to remove the oldest factor to free capacity.cleanAllExpiredZKPFactors
Removes all expired ZKP factors authorized by a valid factor.
Owner and Key Updates
setWasmHash
Updates the WASM hash used for TLS validation. Requires owner authorization.setForceRemoveOldest
Sets the flag to force removal of oldest factors when capacity is reached.addRootProviderCertificate / deleteRootProviderCertificate / cleanRootProviderCertificates
Manage root certificates for providers with ownership restrictions.cleanAllJwks / cleanAllZKPFactors
Clear all JWKs or ZKP factors with ownership rights.updateRecoveryPhrase / updateJwkUpdateKey / updateSeedPhrase
Update recovery, JWK update, and owner public keys respectively, with signature verification.updateZkid
Update all related identity parameters, keys, and certificates atomically with verification.deleteJwkModulus / deleteZKPfactor / deleteZKPfactor_
Delete JWK or ZKP factors with owner authorization.changeSeedPhrase / acceptCandidateSeedPhrase / deleteCandidateSeedPhrase
Multi-step process to change owner public key with candidate proposal and acceptance by recovery key.
Security Card Management
addSecurityCard
Adds a security card with public key and signature. Limits the number of cards.turnOffSecurityCards / turnOnSecurityCards
Enable or disable security card requirement.deleteSecurityCard / deleteAllSecurityCards
Removes single or all security cards.
Transaction Management
sendTransaction
Sends a transaction immediately if security cards are off and the factor is valid.submitTransaction
Submits a transaction to the queue requiring confirmation if security cards are on.confirmTransaction
Confirms and executes a queued transaction by an authorized security card.removeExpiredTransactions
Internal cleanup of expired queued transactions.exchangeToken / exchangeTokenWithOwner
Exchange tokens authorized by a valid factor or owner.
Auxiliary Functions
setMaxCleanupTxns
Sets the maximum number of transactions to clean per cleanup operation.setMinValue
Sets the minimum allowed transaction value.generateTrxId
Generates a unique transaction ID based on block timestamp and logical time.getExpirationBound
Computes the timestamp threshold to determine expired transactions.getSendFlags
Computes message sending flags based on whether all balance is to be sent.
Getter Functions
getTransaction
Returns a specific transaction by ID.getTransactions
Returns all non-expired transactions currently in the queue.getTransactionIds
Returns all transaction IDs currently queued.getZKPEphemeralPublicKeys
Returns all stored ZKP ephemeral public keys.getTimeStamp
Returns the current block timestamp.getSecurityCardKeys
Returns public keys of all added security cards.get_epk_expire_at
Returns the expiration timestamp for a given ephemeral public key.getVersion
Returns contract version and name.
Important Implementation Details and Algorithms
Composite Key for Factors:
ZKP factors are stored in a mapping with keys generated by combining a 64-bit expiration timestamp as the most significant bits and the least significant 192 bits of the ephemeral public key. This allows ordered iteration and quick expiration checks.WASM TLS Validation:
The contract integrates with an external WebAssembly module for TLS validation of JWK modulus data. It executes the external WASM function and validates results before storing JWKs.Signature and Proof Verification:
Multiple checks ensure all public keys and updates are properly signed usingtvm.checkSign. Zero-knowledge proofs are verified via thegosh.vergrth16method with inputs hashed bygosh.poseidon.Transaction Queue with Expiration:
Transactions can be queued and require confirmation by security cards. Expired transactions are cleaned periodically with a configurable cleanup limit.Multi-step Ownership Change:
Changing the owner public key involves proposing a candidate factor with an expiration and acceptance by the recovery key, preventing unauthorized immediate ownership changes.Security Cards:
Security cards add an extra authentication layer. When enabled, transaction sending requires confirmation by one of the registered security cards.Limits and Expiration Controls:
Strict checks on expiration timestamps prevent replay or use of stale factors/keys. Limits on the number of factors, JWKs, security cards, and queued transactions prevent resource exhaustion.
Interaction with Other Components
Modifiers:
The contract inherits fromModifierswhich likely provides access control modifiers such asonlyOwnerPubkey.External WASM Module:
Invokes TLS validation through a WASM module named"docs:tlschecker/[email protected]"and function"tlscheck".Cryptographic Utilities (
gosh):
Uses cryptographic helper functions likeposeidonhashing,vergrth16proof verification, andcnvrtshellqfor token exchanges.TVM System:
Relies on TVM features such astvm.checkSign,TvmCell, and structured transactions.
Visual Diagram
classDiagram
class Multifactor {
+constructor()
+addJwkModulus()
+deleteJwkModulusByUpdateJwkKey()
+cleanExpiredJwks()
+addZKPfactor()
+deleteZKPfactorByItself()
+cleanExpiredZKPFactors()
+cleanOldestZKPFactor()
+setWasmHash()
+addRootProviderCertificate()
+deleteRootProviderCertificate()
+updateRecoveryPhrase()
+updateSeedPhrase()
+changeSeedPhrase()
+acceptCandidateSeedPhrase()
+deleteCandidateSeedPhrase()
+addSecurityCard()
+turnOffSecurityCards()
+submitTransaction()
+confirmTransaction()
+removeExpiredTransactions()
+exchangeToken()
+setMaxCleanupTxns()
+setMinValue()
+getTransaction()
+getTransactions()
+getZKPEphemeralPublicKeys()
}
class Transaction {
+id: uint64
+creator: uint256
+dest: address
+value: uint128
+cc: mapping
+sendFlags: uint16
+payload: TvmCell
+bounce: bool
}
class JWKData {
+modulus: bytes
+modulus_expire_at: uint64
}
Multifactor "1" *-- "many" Transaction : manages
Multifactor "1" *-- "many" JWKData : manages