fix(mint/auth): make a fresh 0.21.0 auth mint work end-to-end#1004
Open
robwoodgate wants to merge 31 commits into
Open
fix(mint/auth): make a fresh 0.21.0 auth mint work end-to-end#1004robwoodgate wants to merge 31 commits into
robwoodgate wants to merge 31 commits into
Conversation
…h BLS12-381 cryptography
… verification - Fixed keyset v3 derivation logic and ID generation - Replaced additive blinding logic with BLS multiplicative blinding - Handled backwards compatibility for DLEQ skipping and verifying - Implemented batch BLS pairing verification for unblinded signatures - Removed redundant dummy DLEQ generation in BLS operations - Fixed failing unit tests and resolved type-checking union issues
…ell into fix/v3-y-and-dleq-null
fix v3 Proof.Y hash-to-curve and BlindedSignature dleq=None
c6a730a to
442caa4
Compare
9c8d3cb to
b388db9
Compare
b388db9 to
1b2f28a
Compare
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.
Stacked on #999
This PR is a fix for BLS implementation PR #999.
Summary
Five coupled fixes that surface together when a fresh Nutshell 0.21.0 auth mint runs against any OIDC provider (e.g. Keycloak 25+) and a v3 (BLS) keyset is generated on first start. Verified end-to-end against a local Keycloak + this branch + cashu-ts.
Each fix is small; bundled because they share one architectural root —
AuthLedgerinherits the mint CRUD (LedgerCrudSqlite) and the globalmint_input_fee_ppksetting, while the auth migrations chain / response models / user-id contract / auth-side CRUD never kept up.The five fixes
Force
input_fee_ppk=0on auth keyset generation. Auth proofs are NUT-22 amount-1 bearer tokens — never swapped or melted.AuthLedger.verify_blind_authalready explicitly skips fee calculation. ButLedger.activate_keysetreadssettings.mint_input_fee_ppkunconditionally, so any mint with a non-zero global fee bakes that value into the auth keyset id — semantically wrong, and breaks wallet-side id re-derivation. Matches CDK's behaviour (crates/cdk/src/mint/builder.rsforces fee=0 for the Auth unit). Implementation:LedgerKeysetsgets a per-instancekeyset_input_fee_ppk: Optional[int] = Nonedefaulting tosettings.mint_input_fee_ppk;AuthLedgeroverrides to0. No behaviour change for non-auth ledgers.m003: addfinal_expirycolumn to authkeysetstable.LedgerCrudSqlite.store_keysetINSERTsfinal_expiry(added on the mint side in m031 for keysets v2). Auth migrations stopped at m002, so v3 keyset generation crashes withno column named final_expiry. Mirrors mint m031.m004: align authpromisestable with the mint-side schema. The mint side evolvedpromisesto addmint_quote/swap_id(m023) andmelt_quote/signed_at+ drop thec_ NOT NULLconstraint (m032-ish).LedgerCrudSqlite.store_promiseINSERTs the full column set, so auth-side blind minting (first exercised by v3 BAT issuance at 0.21+) trips firstno column named mint_quotethenNOT NULL constraint failed: promises.c_. SQLite path rebuilds the table; Postgres path uses the ALTER chain.Tolerate missing
subclaim in clear-auth tokens._get_userhard-codeddecoded_token[\"sub\"], raisingKeyErrorwhen the IdP omitssubfrom access tokens. Keycloak 25+ does this by default for public clients (theoidc-subject-mapperdeclared in the testcashu-realm.jsongets silently dropped on import). CDK'sverify_catdoesn't readsubat all and works against the same realm. Fall back topreferred_usernamethenazpso single-user-per-realm rate-limit tracking still works without changing happy-path semantics for IdPs that shipsub. Cross-IdP, not Keycloak-specific.AuthLedgerCrudSqlite.get_keyset: useMintKeyset.from_rowinstead ofMintKeyset(**row). The mint-side equivalent (cashu/mint/crud.py:962) usesfrom_rowcorrectly; the auth-side spreads the row dict directly into the constructor, which passesamountsthrough as the raw stringified-JSON SQLite stores (e.g.\"[1]\"). Iteration overself.amountswould then walk characters instead of list elements, producing junk key material. Dead code under the current wiring —cashu/mint/startup.py:94constructsAuthLedgerwithcrud=LedgerCrudSqlite()(whoseget_keysetis the correctfrom_rowversion), andself.auth_crud = AuthLedgerCrudSqlite()is only used for user CRUD (get_user/create_user/update_user), never forget_keyset. Fixed anyway as a 1-line free fix that removes a landmine for the eventual switch-to-AuthLedgerCrudSqlitecleanup noted below.Out of scope (worth a follow-up)
The underlying smell is
AuthLedgerusingLedgerCrudSqliteinstead of the (existing-but-unused)AuthLedgerCrudSqlite, whose leanerstore_keyset/store_promisealready match the auth m001 schema and would obviate (1)–(3). Switching CRUDs requires adding several missing methods toAuthLedgerCrud(store_blinded_message,update_keyset,bump_keyset_*, balance logs) — too wide for this PR.Test plan
/v1/auth/blind/keysetsexposes the keyset.ClearAuthFailedErrordue to missingsub).keyset_input_fee_ppkdefaults toNone→ falls through tosettings.mint_input_fee_ppk.Refs #999.