As of 3 Nov 2026, Particle Network has 1 audit report on Trustblock, by CertiK, dated 27 May 2023. That report lists no open critical findings.
Record last updated . It holds audits and findings, contracts and incidents up to Nov 2026. Trustblock does not review code.
Newest first
| Audit | Security firm | Date | Scope | Critical findings | Report |
|---|---|---|---|---|---|
| Particle Network - MPC Audit | Security firm: CertiK | Date: | Scope: Not recorded (see the report) | No open critical findings | Open · skynet.certik.com |
Statuses are the security firm’s own, from each report.
| Severity | Open | Acknowledged | Fixed |
|---|---|---|---|
| Critical | 0 | 0 | 0 |
| High | 0 | 0 | 1 |
| Medium | 0 | 0 | 3 |
| Low | 4 | 0 | 5 |
When Party 1 creates the second message of the protocol, it verifies the proof coming from Party 2 proving Party 2 owns the secret key share relative to the committed public key. Such verification is implemented at the pointed lines and checks that the proof is valid in respect to the public key included in the `DLogProof` object. However, the public key share which is effectively used is the one included in the `KeyGenFirstMsg::public_share` field created and shared by Party 2. So, Party 1 must check that such public keys, the one included in the `DLogProof` and the one in `KeyGenFirstMsg`, match. Similarly, when Party 2 verifies the `DLogProof` after receiving the two messages from Party 1, it must check that the public key included in `DLogProof::pk` matches the one supplied at `KeyGenSecondMsg::comm_witness::public_share`. In absence of such checks, one of the party, acting maliciously, can gather knowledge of the secret share of the counterparty crafting a public share based on the counterparty's one, as it break the security assumption of correct key generation and the guarantees provided by the ownership proof represented by `DLogProof`.
Open the reportThe `verify` function implements the verification of an ECDSA signature. In doing that, the `u1_plus_u2_bytes` contains the elliptic curve point which is the result of the EC addition of two points computed from the two components included in the signature, the signer public key, and the message to verify. Such addition over the `secp256k1` curve is implemented in the `curv` crate and it panics if the result of the addition is the point at infinite. So, such condition is not handled by the implementation, which panics instead of returning a false result for the `verify` function. This behavior could be exploited by an attacker by producing a fake signature which lets the pointed addition result in the point at infinite and cause a panic in the verifier. Considering that the codebase in scope is a library and it may be used in runtimes other than blockchain ones, panics should be always carefully documented as they can cause the crash of function caller. Moreover, the panic refers to an error condition which should be managed inside the `verify` function, since it is a possible situation.
Open the reportThe `verify_commitments_and_dlog_proof` method returns a `Result` enum to indicate the outcome its verification logic. In the positive case the `Result` can be unwrapped as a `KeyGenSecondMsg` (or `EphKeyGenSecondMsg) while in the negative case a `ProofError` should be returned. However, the function logic never returns a `ProofError`. Instead, it panics through the usage of an `assert`. Such behavior is not advised as: 1. The logic does not conform to the declared return type, and a caller would expect a `ProofError` when an invalid proof is provided; 2. Since the codebase in scope is a library on which other implementations may be based, panics should be carefully documented as they potentially cause the crash of the caller.
Open the reportThe function `generate_keypair_and_encrypted_share` is used to generate the Paillier encryption and decryption keys. However, the decryption key `dk` and the variable `randomness` both remain in memory after the end of the function call.
Open the reportDuring the key generation phase the function `create_commitments` is responsible for generating the secret share $x_1$. This secret share $x_1$ is a randomly generated value. This value need not be between the ranges of $\{\frac{q}{3},\ldots ,\frac{2q}{3}\}$. Therefore completeness need not hold for the zero knowledge of a Paillier encryption of a discrete log as defined in [Lindell](https://eprint.iacr.org/2017/552.pdf). It should be noted that the proof used for the Paillier encryption of a discrete log is found in [Gennaro, Goldfeder, and Narayanan](https://eprint.iacr.org/2016/013.pdf). However, completeness is also not guaranteed in this case.
Open the reportThe `create_commitments` and `create_commitments_with_fixed_secret_share` act as factories for the `KeyGenFirstMsg` representing the Party 1 message. Their implementations differ in the fact that the former generates a random `secret_share` while the latter takes it as a parameter. Since the difference between the two function only consists in the `secret_share` parameter, the two bodies presents the exact same code, which an error-prone approach for code maintainability.
Open the reportThe implementation explicitly fulfills with zeroes memory location containing sensible data, e.g. private keys or one-time random values, when variables referring to them go out of scope and should be wiped by the compiler, to avoid that any compiler optimization could leave such data available for exploits or malicious code accessing it. However code at the pointed location only partially wipes the decryption of the partial signature coming from the signing counterparty. In fact variable `s_tag_fe` if fulfilled with zeroes after its usage, but the same operation is not performed on the `s_tag` variable from which `s_tag_fe` is calculated.
Open the reportAs a final output of the key generation sub-protocol, Party 2 obtains the global public key $Q$ and the Paillier encryption of Party 1 private share $c_{key}$. Moreover, during the protocol, Party 2 has recieved the encryption key $pk = N$ of the Paillier keypair generated by Party 1. If $Q$ is generated by Party 2 itself by multiplying its private share with the public Party 1 share $Q_1$, and it was proven that Party 1 hold the relative private share, some additional checks should be performed on $c_{key}$ which should be a decryptable object. Such condition is checked verifying the belonging of $c_{key}$ to $Z^*_{N^2}$. If this is not the case, Party 2 should abort the protocol since the precondition to create a signature is not met.
Open the reportThrowing out a panic may not always be desired in the production codebase, and lacking an error handling mechanism will reduce the robustness of the program. In particular, even if code at the pointed location unwraps values which can only be returned within the `Option::Some` case, they come from a particular implementation of the `ECPoint` trait, which, instead, may generally return a `Option::None`, too. If the underlying elliptic curve or its implementation change, code should be manually inspected in order to replace the `unwrap` usage, which is something to avoid for code maintainability and robustness.
Open the reportThe reports name a repository or files. Open a report to see its scope.
Is this your project? Show this record on your own website. The label states what the record holds, links to this page and updates by itself. It is free and needs no sign-in.
Automatic: the three strongest facts of this project’s own record (its last audit and two more), highlighted. They update with the record. Picking a fact turns Automatic off.
<head><script src="https://widget.trustblock.run/project-widget.min.js" defer></script></head><body><divdata-tb-project-widgetdata-tb-project-slug="particle-network"></div></body>
Paste the code where the label should appear. It uses no API credit and updates by itself.
Something wrong on this page? A missing report, a wrong date, a finding that was fixed since. Tell us and we check it against its source.
Tell us