Repository navigation
Conversation
…ce canonical low-s ECDSA
### Summary of Changes
Resolves **Finding 3 (Medium)** and **Finding 4 (Low)** from the Chronicle workspace security audit in `ValidatorRegistry.sol`:
1. Binds `constructValidatorRegistrationMessageV2` to `address(this)` and `block.chainid` to prevent cross-registry and cross-chain Proof-of-Possession (PoP) signature replay[cite: 28, 33].
2. Enforces canonical low-s check in `_lift` to eliminate ECDSA signature malleability and protects occupied validator slots with explicit error messaging[cite: 28, 33].
---
### Vulnerability Analysis
- **PoP Replay across Chains / Registries (Finding 3):**
- Without contract and chain domain separation, a validator registration signature was entirely deterministic based on the public key coordinates alone.
- An observer capturing a registration signature on Chain A could replay the same byte payload to register the validator on Chain B without holding the corresponding private key at registration time.
- **Signature Malleability & Slot Collisions (Finding 4):**
- High-s values (`s > secp256k1n / 2`) permitted two distinct valid on-chain encodings for the same registration signature, violating byte-uniqueness assumptions.
- Missing guards on occupied IDs risked silent evictions of active validators[cite: 33].
---
### Key Remediations
- **Domain Separation Enforcement (`constructValidatorRegistrationMessageV2`):**
```solidity
return keccak256(
abi.encodePacked(
"\x19Ethereum Signed Message:\n32",
keccak256(
abi.encodePacked(
address(this),
block.chainid,
_CONTEXT,
pubKey.x,
pubKey.y
)
)
)
);
Member
|
Risk accepted and/or simply not applicable. Next time, please open an issue first to discuss. For security relevant issues, send an email to |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary of Changes
Resolves Finding 3 (Medium) and Finding 4 (Low) from the Chronicle workspace security audit in
ValidatorRegistry.sol:constructValidatorRegistrationMessageV2toaddress(this)andblock.chainidto prevent cross-registry and cross-chain Proof-of-Possession (PoP) signature replay[cite: 28, 33]._liftto eliminate ECDSA signature malleability and protects occupied validator slots with explicit error messaging[cite: 28, 33].Vulnerability Analysis
PoP Replay across Chains / Registries (Finding 3):
Signature Malleability & Slot Collisions (Finding 4):
s > secp256k1n / 2) permitted two distinct valid on-chain encodings for the same registration signature, violating byte-uniqueness assumptions.Key Remediations
constructValidatorRegistrationMessageV2): ```solidity return keccak256( abi.encodePacked( "\x19Ethereum Signed Message:\n32", keccak256( abi.encodePacked( address(this), block.chainid, _CONTEXT, pubKey.x, pubKey.y ) ) ) );Canonical Low-s Assertion (_lift):
require(
feedRegistrationSigV2.s
<= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0,
"ValidatorRegistry: signature s not canonical"
);
ID Collision Guard: Added require(current == address(0), "ValidatorRegistry: id occupied"); to prevent overwriting active validators[cite: 33].
Verification Compiled with solc 0.8.24 (and 0.8.16 base): clean compilation with zero warnings. Verified rejection of high-s inverted signatures.Verified domain mismatch rejection between differing chainid or contract instances.