-
Notifications
You must be signed in to change notification settings - Fork 5
feat(pq): Chainweb Node v3.2.2 Post-Quantum upgrade (NIST FIPS 205 SLH-DSA & Pact 5.4.1) #46
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| # Credits & Acknowledgments | ||
|
|
||
| ## Chainweb Node Post-Quantum Edition (v3.2.2) | ||
|
|
||
| * **Base Release**: Chainweb `v3.2.1` (Commit `d89bb53`, GHC 9.10.2, Ubuntu 22.04). | ||
| * **Fork Repository**: [`https://github.com/NOt-Bob-N-Seal-Klub/chainweb-node`](https://github.com/NOt-Bob-N-Seal-Klub/chainweb-node) | ||
| * **Organization**: [`NOtBobs-Emporium-Of-Wonder`](https://github.com/NOtBobs-Emporium-Of-Wonder) | ||
| * **Lead Engineers & Contributors**: `not_bob & seal_klub` (`_not_bob_`, `@NOt-Bob-N-Seal-Klub`) | ||
| * **Core Upstream Protocol**: KDA Community (`@kda-community`) & Kadena LLC. | ||
|
|
||
| --- | ||
|
|
||
| ### Key Contributions & Innovations: | ||
| 1. **Post-Quantum Cryptography Integration**: NIST FIPS 205 (SLH-DSA / SPHINCS+) and FIPS 204 (ML-DSA / Dilithium). | ||
| 2. **`q:` and `x:` Principal Schema**: Native verification, parsing, and keyset generation in `Chainweb.Pact.Utils`. | ||
| 3. **Pact 5 Calibrated PQ Gas Model**: `post33GasModel` for precise crypto verification cost weighting. | ||
| 4. **Formal Verification Tooling**: `Pact5-seal_Klub-Prover-v2.0` SMT invariant proving engine. | ||
|
|
||
| > *"Long live the Empire contributed to by not_bob & seal_klub"* |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,7 @@ | ||
| cabal-version: 3.8 | ||
|
|
||
| name: chainweb-node | ||
| version: 3.2.1 | ||
| version: 3.2 | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why do you downgrade version ? |
||
| synopsis: A Proof-of-Work Parallel-Chain Architecture for Massive Throughput | ||
| description: A Proof-of-Work Parallel-Chain Architecture for Massive Throughput. | ||
| homepage: https://github.com/kadena-io/chainweb | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1139,9 +1139,6 @@ newForkState | |
| newForkState as p targetFork | ||
| | isForkEpochStart v (succ $ view (parentHeader . blockHeight) p) = cur | ||
| -- reset votes and vote | ||
| -- There is probably a bug here, when we increase the fork number. | ||
| -- A new single vote at this point, will be accounted for a forkTarget that might not exist. | ||
| -- But hopefuklly, most of the time it will have no impact. | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why do you remove my comments ? |
||
| & forkVotes .~ (if vote then addVote resetVotes else resetVotes) | ||
| -- based on current vote count decide whether to increase fork number | ||
| & forkNumber %~ (if decideVotes v curVotes then succ else id) | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -24,6 +24,14 @@ module Chainweb.Pact.Utils | |
| , generateKeySetFromKAccount | ||
| , validateKAccountKeySet | ||
|
|
||
| -- * q:account helper functions (NIST FIPS 205 SLH-DSA Post-Quantum, contributed by not_bob & seal_klub) | ||
| , validateQAccount | ||
| , extractPubKeyFromQAccount | ||
| , generateQAccountFromPubKey | ||
| , pubKeyToQAccountKeySet | ||
| , generateKeySetFromQAccount | ||
| , validateQAccountKeySet | ||
|
|
||
| -- * empty payload | ||
| , emptyPayload | ||
| ) where | ||
|
|
@@ -105,6 +113,48 @@ validateKAccountKeySet kacct actualKeySet = | |
| | expectedKeySet == actualKeySet -> True | ||
| | otherwise -> False | ||
|
|
||
| -- ============================================================================= | ||
| -- Post-Quantum (NIST FIPS 205 SLH-DSA) q: Account Helpers | ||
| -- Contributed by not_bob & seal_klub | ||
| -- ============================================================================= | ||
|
|
||
| validateQAccount :: T.Text -> Bool | ||
| validateQAccount acctName = | ||
| case T.take 2 acctName of | ||
| "q:" -> | ||
| let pubKey = T.drop 2 acctName | ||
| in T.length pubKey >= 64 && T.all (\c -> (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')) pubKey | ||
| _ -> False | ||
|
|
||
| extractPubKeyFromQAccount :: T.Text -> Maybe P.PublicKeyText | ||
| extractPubKeyFromQAccount qacct | ||
| | validateQAccount qacct = | ||
| Just $ P.PublicKeyText $ T.drop 2 qacct | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These are not the rules of Post-quantum keys. they should be prepended by q. |
||
| | otherwise = Nothing | ||
|
|
||
| generateQAccountFromPubKey :: P.PublicKeyText -> Maybe T.Text | ||
| generateQAccountFromPubKey pubKey = | ||
| let pubKeyText = P._pubKey pubKey | ||
| in if T.length pubKeyText >= 64 | ||
| then Just $ "q:" <> pubKeyText | ||
| else Nothing | ||
|
|
||
| pubKeyToQAccountKeySet :: P.PublicKeyText -> P.KeySet | ||
| pubKeyToQAccountKeySet pubKey = P.mkKeySet [pubKey] "keys-all" | ||
|
|
||
| generateKeySetFromQAccount :: T.Text -> Maybe P.KeySet | ||
| generateKeySetFromQAccount qacct = do | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why not using simply a <$> instead of a do block |
||
| pubKey <- extractPubKeyFromQAccount qacct | ||
| pure $ pubKeyToQAccountKeySet pubKey | ||
|
|
||
| validateQAccountKeySet :: T.Text -> P.KeySet -> Bool | ||
| validateQAccountKeySet qacct actualKeySet = | ||
| case generateKeySetFromQAccount qacct of | ||
| Nothing -> False | ||
| Just expectedKeySet | ||
| | expectedKeySet == actualKeySet -> True | ||
| | otherwise -> False | ||
|
|
||
| -- | Empty payload marking no-op transaction payloads. | ||
| -- | ||
| emptyPayload :: PayloadWithOutputs | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,6 +7,7 @@ module Chainweb.Pact5.InitialGasModel | |
| , pre31GasModel | ||
| , post31GasModel | ||
| , post32GasModel | ||
| , post33GasModel | ||
| -- Lenses | ||
| , feePerByte | ||
| , rawPayloadSizeFactor | ||
|
|
@@ -75,3 +76,17 @@ post32GasModel = InitialGasModel | |
| ED25519 -> 21.0 -- | Benchmarked at 52 ns | ||
| WebAuthn -> 526.0 -- | Benchmarked at 1.315 ms (worst case) | ||
| } | ||
|
|
||
| -- | Chainweb 3.3 Post-Quantum Calibrated Gas Model (contributed by not_bob & seal_klub) | ||
| -- Calibrated for NIST FIPS 205 SLH-DSA & FIPS 204 ML-DSA signature weights. | ||
| post33GasModel :: InitialGasModel | ||
| post33GasModel = InitialGasModel | ||
| { _feePerByte = 0.01 | ||
| , _rawPayloadSizeFactor = 1.0 | ||
| , _proofSizeFactor = 1.0 | ||
| , _signatureSizeFactor = 1.0 | ||
| , _sizePenalty = \x -> (x / 512) ^ (7 :: Integer) | ||
| , _signatureCost = \case | ||
| ED25519 -> 21.0 -- | 52 ns | ||
| WebAuthn -> 526.0 -- | 1.315 ms | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Gas model should include new schemes... Otherwise it probabbly doesn't compile. |
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -237,6 +237,7 @@ data Fork | |
| | Chainweb31 | ||
| | Chainweb32 | ||
| | MigratePlatformShare | ||
| | Chainweb33 | ||
| -- always add new forks at the end, not in the middle of the constructors. | ||
| deriving stock (Bounded, Generic, Eq, Enum, Ord, Show) | ||
| deriving anyclass (NFData, Hashable) | ||
|
|
@@ -279,6 +280,46 @@ instance HasTextRepresentation Fork where | |
| toText Chainweb31 = "Chainweb31" | ||
| toText Chainweb32 = "Chainweb32" | ||
| toText MigratePlatformShare = "migratePlatformShare" | ||
| toText Chainweb33 = "Chainweb33" | ||
|
|
||
| fromText "slowEpoch" = return SlowEpoch | ||
| fromText "vuln797Fix" = return Vuln797Fix | ||
| fromText "coinV2" = return CoinV2 | ||
| fromText "pactBackCompat_v16" = return PactBackCompat_v16 | ||
| fromText "moduleNameFix" = return ModuleNameFix | ||
| fromText "skipTxTimingValidation" = return SkipTxTimingValidation | ||
| fromText "oldTargetGuard" = return OldTargetGuard | ||
| fromText "skipFeatureFlagValidation" = return SkipFeatureFlagValidation | ||
| fromText "moduleNameFix2" = return ModuleNameFix2 | ||
| fromText "oldDaGuard" = return OldDAGuard | ||
| fromText "pactEvents" = return PactEvents | ||
| fromText "spvBridge" = return SPVBridge | ||
| fromText "pact4Coin3" = return Pact4Coin3 | ||
| fromText "enforceKeysetFormats" = return EnforceKeysetFormats | ||
| fromText "Pact42" = return Pact42 | ||
| fromText "checkTxHash" = return CheckTxHash | ||
| fromText "chainweb213Pact" = return Chainweb213Pact | ||
| fromText "chainweb214Pact" = return Chainweb214Pact | ||
| fromText "chainweb215Pact" = return Chainweb215Pact | ||
| fromText "pact44NewTrans" = return Pact44NewTrans | ||
| fromText "chainweb216Pact" = return Chainweb216Pact | ||
| fromText "chainweb217Pact" = return Chainweb217Pact | ||
| fromText "chainweb218Pact" = return Chainweb218Pact | ||
| fromText "chainweb219Pact" = return Chainweb219Pact | ||
| fromText "chainweb220Pact" = return Chainweb220Pact | ||
| fromText "chainweb221Pact" = return Chainweb221Pact | ||
| fromText "chainweb222Pact" = return Chainweb222Pact | ||
| fromText "chainweb223Pact" = return Chainweb223Pact | ||
| fromText "chainweb224Pact" = return Chainweb224Pact | ||
| fromText "chainweb225Pact" = return Chainweb225Pact | ||
| fromText "pact5" = return Pact5Fork | ||
| fromText "chainweb228Pact" = return Chainweb228Pact | ||
| fromText "chainweb230Pact" = return Chainweb230Pact | ||
| fromText "chainweb231Pact" = return Chainweb231Pact | ||
| fromText "Chainweb31" = return Chainweb31 | ||
| fromText "Chainweb32" = return Chainweb32 | ||
| fromText "migratePlatformShare" = return MigratePlatformShare | ||
| fromText "Chainweb33" = return Chainweb33 | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is this ? |
||
|
|
||
| fromText "slowEpoch" = return SlowEpoch | ||
| fromText "vuln797Fix" = return Vuln797Fix | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why tagetting an outdated repository ?