Overview
shyware is a shared anonymous wrapper architecture, not just a voting daemon. The cleanest way to read the system is:shyvotingdemonstrates the two-list anonymous ballot apparatus.shywireandshycontractsdemonstrate the same structural separation in value transfer and financing flows that are immediately legible to regulated operators.shycustodydemonstrates pooled-asset custody, issuance, redemption, and demurrage as a distinct commodity/warehouse species that usesshywireas its transfer rail without collapsing into it.shysharesdemonstrates that the same apparatus generalizes into weighted governance with canonical queued actions.
Preferred non-ZK voting/governance tier — IDV-attested public key; receipt store linkable under lawful process
identity_hash = SHA-256(voter_pub_key ‖ poll_id)
Because sk_v is generated on the device at vote time and discarded immediately after
voter_sig is produced, the IDV provider can never hold it. A forged ballot would require
inverting a random Ed25519 keypair — structural oracle prevention without ZK overhead.
High-assurance ZK tier — commitment-blind; receipt store unlinkable even under subpoena
identity_hash = ZKNullifier = MiMC(person_secret, poll_id)
commitment and didit_commitment_sig are private circuit witness inputs and must not
appear in the transaction payload. The on-chain record contains only the nullifier
and the Groth16 proof. This is what makes the ZK tier oracle-free with respect to even the
linkage store operator — there is no on-chain field the IDV provider can use to correlate
nullifier → commitment → identity.
List 1 / List 2 separation
The anonymity guarantee rests on a single structural property: no common key exists between List 1 and List 2.ballot_id is the hash of a random client-generated nonce. identity_hash is derived
from the voter’s ephemeral device key (or ZK secret). These two values share no
derivation path in either tier.
ZK nullifier circuit (high-assurance tier)
The Groth16 circuit proves two statements simultaneously without revealingperson_secret:
IDV binding
Preferred non-ZK tier: an IDV provider such as Didit issues an Ed25519 signature overSHA-256(voter_pub_key ‖ poll_id) after completing biometric identity verification.
The runtime verifies this signature using the configured provider public key.
This binds the ephemeral voter device key — and therefore identity_hash — to a real,
verified person. Neither the IDV provider nor the canonical runtime can link the
ballot_id to the voter’s identity without the ballot_nonce, which the voter
retains in the off-chain receipt store.
ZK tier: the IDV provider issues an Ed25519 signature over
SHA-256(commitment ‖ poll_id) where commitment = MiMC(person_secret). This signature
is absorbed as a private circuit witness and never appears on-chain.
Count-match invariant
At every committed block:state.ExecuteTx before every ballot is accepted. A missing
or extra record in either list causes executeBallotCast to return an error and the
transaction to be rejected.
Managed tally signing
At poll close,executePollClose calls signer.Sign with the payload:
AWS KMS + Azure Managed HSM. The verifying key is stored in
Tally.PublicKey (DER-encoded) so any party can verify the signature with the
verify package and no operator dependency.
Sybil-audit signal (receipt confirmation)
After a poll closes, voters can submitTxTypeConfirmReceipt transactions to acknowledge
that their identity_hash appears in List 2. The aggregate confirmed_count K vs total
N is returned in the tally. The gap N-K is an observable Sybil signal: voters who
cannot confirm their receipt may have had their participation fabricated.
No biometrics, no ZK, no new oracle — the mechanism is structurally present in the
two-list protocol.