I4: verify_adaptor — Schnorr adaptor verification in-VM (fixes #112, stacks on #84) - #113
Closed
liqdmetal wants to merge 5 commits into
Closed
I4: verify_adaptor — Schnorr adaptor verification in-VM (fixes #112, stacks on #84)#113liqdmetal wants to merge 5 commits into
liqdmetal wants to merge 5 commits into
Conversation
…mit, asset_balance, ec_add) Five new DVM-BASIC intrinsics (gated semver >= 9.0.0, so existing contracts are unaffected — the func_table Range mechanism): - verify_sig(pubkey_hex, message, sig_hex) -> Uint64: Ed25519 in-VM signature verification. Enables anonymous contract authorization (caller proves key ownership in encrypted SCDATA at ringsize >= 4, no SIGNER()/ringsize-2) — the K0 Fix C path. Gas 250k. Stdlib, no new deps. - hash_to_point(input) -> String: HashToPoint(HashtoNumber(input)), 33-byte compressed G1 hex, deterministic across nodes. Pinned to the protocol generator derivation (algebra_pedersen.go). Gas 30k. - pedersen_commit(value, blind_hex) -> String + verify_commit(value, blind_hex, commit_hex) -> Uint64: v*G + r*H with NUMS H (hash-to-point of PROTOCOL_CONSTANT+H), 32-byte blind (256-bit hiding). Commit on-chain, reveal off-chain, SC verifies — no oracle trust. Gas 45k. - asset_balance(asset_hex) -> Uint64: reads the SC's OWN stored balance for any asset (incl. DERO) via BalanceLoader(scid, asset). Closes the gap where derovalue()/assetvalue() only report the current tx's incoming value. Gas 2k. - ec_add(p1_hex, p2_hex) -> String: homomorphic accumulation of compressed G1 points — ec_add(c1,c2) == pedersen_commit(v1+v2, b1+b2), enabling commitment-state updates (e.g. AMM reserves) without revealing deltas. Gas 15k. Tests (dvm/verify_sig_test.go): 6 test functions covering valid/tampered/ malformed inputs, determinism, version gate, the homomorphic property, and BalanceLoader wiring. Consensus note: new intrinsics change VM state output -> hard fork (DVM version bump). The version gate means old contracts keep running unchanged. This is the foundation for K0 Fix C and confidential settlement. Also carries the build-manifest fix (go.mod/go.sum): the current tree does not build from a fresh clone.
Regenerates vendor/ via go mod tidy + go mod vendor (adds missing vendor/modules.txt) so the tree builds from a fresh clone without -mod=mod. Deps unchanged.
community-dev base calls l.Operation.KickReader(), which no published chzyer/readline implements (v1.5.1) -> wallet-cli fails to compile from a fresh clone. Replace with the same UI shim used on the main fork branch: _ = l.Operation (read-unblock helper, wallet-only, not consensus).
… in-VM The cross-chain atomic primitive (PTLC-style), on DERO's own bn256 curve. verify_adaptor(pubkey_hex, message_hex, adaptor_sig_hex) -> Uint64 A Schnorr adaptor signature proves 'the holder of x (P = x*G) can produce a valid signature on m once a tweak t is revealed' WITHOUT revealing t. Two chains share a pre-signed adaptor; whichever party reveals the tweak completes both transactions atomically — the atomic-swap settlement primitive for DERO. Math (bn256, order n): e = ReducedHash(R'||P||m); valid iff s'*G == R' + e*P Serialization: 33B pubkey + message + 97B adaptor sig (64B s' + 33B R'). Consensus-safety: pure verification (no witness material, no key recovery, no tweak disclosure); gated >= 10.0.0; malformed input -> 0, never panics. TestVerifyAdaptor: builds a real adaptor sig (same construction), verifies valid=1, wrong key/msg/tampered/malformed=0, version gate (9.0.0 hidden). Full dvm suite green. Stacks on the v9 intrinsics (PR DEROFDN#84); 250k gas.
Two gaps pinned by TestWargameVerifyAdaptor*: 1. SCALAR MALLEABILITY: s' was taken raw from sig_bytes[:64] with no s' < n check. ScalarMult reduces mod n internally, so s' and s'+n produced the same point -> a non-canonical (s >= n) signature still verified as 1. Now rejected (low-s normalization) so the encoded signature is unique and non-malleable. 2. NON-CANONICAL POINT DECODE: P and R decoded with DecodeCompressed + err==nil, which accepts x >= p encodings (the chain-split class the I3/v9 PRs close with strictDecodeG1). Both now reject x >= p before decode, matching the strict decoder boundary. Valid adaptor still verifies; full dvm suite green.
Author
|
Superseded by PR #128 — the consolidated intrinsics package. Same code, one reviewable PR with no vendor noise. |
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
I4 from the intrinsic agenda (P0):
verify_adaptor(pubkey_hex, message_hex, adaptor_sig_hex) -> Uint64— Schnorr adaptor-signature verification in the VM, on DERO's own bn256 curve (no new dependencies). This is the cross-chain atomic settlement primitive (PTLC-style).What it enables
A Schnorr adaptor signature proves "the holder of x (P = x·G) can produce a valid signature on m once a tweak t is revealed" — without revealing t. Two chains share a pre-signed adaptor; whichever party reveals the tweak completes both transactions atomically. This is the settlement rail primitive for cross-chain atomic swaps:
Math
where adaptor_sig = (s', R'): s' = r + e·x + t, R' = (r+t)·G. When the prover reveals t, the counterparty extracts the real signature: s = s' − t.
Serialization
pubkey_hex— 33-byte compressed G1message_hex— raw message bytesadaptor_sig_hex— 97 bytes = 64-byte big-endian s' + 33-byte compressed R'Consensus safety
>= 10.0.0(same HF window as verify_proof, L-series)Tests (
TestVerifyAdaptor)Builds a real Schnorr adaptor signature (same construction the intrinsic verifies) and asserts:
Full dvm suite green.
Relationship
>= 10.0.0gate shared with verify_proof (feat(dvm): verify_proof PoC with executing-block roothash bind (fixes #93) #94)verify_sig(Ed25519 auth) andverify_proof(ZK) — the three-verification toolkit for settlement contractsBranch:
feature/dvm-i4-verify-adaptorin the forkliqdmetal/derohe-improvements-by-liqdmetal(stacked onfeature/dvm-v9-intrinsics).