Skip to content
This repository has been archived by the owner on Oct 28, 2024. It is now read-only.

Semaphore Circuit Idea Specification

HaRold edited this page Oct 16, 2018 · 2 revisions

The Semaphore signalling mechanism allows you to sign signals and attest to events in an anonymous way, signals by the same person can't be linked with each other as long as they don't violate the unique constraints, but if the same person emits two signals with the same unique constraint then they will be linkable.

For every signal there are 3 public variables, and an arbitrary number of private variables, this allows on-chain contracts to verify or enforce public inputs which won't de-anonymise the signaller.

Signal Registry

Register a signal by passing its schema to the smart contract, this will generate a unique ID

Signal Schema

The signal schema consists of a list of parameters, their types and schema properties.

[
  ["date", ["validation-operation", "arg1", "arg2"], true]
]
Name Validation Unique?
Name of signal Array with 1, 2 or 3 arguments Include value in hash

The signal produces two hashes, one based on the type of signal and another based on values which are needed to distinguish the signal from others.

The rules in the schema are interpreted in order, they act as instructions for a validator program which allows for arbitrary rules to be enforced, the resulting state are the two hashes which have been verifiably generated.

H = lambda iv, *data: MiMC.hash(iv, data)
inputs = [ # 16 inputs
 # (name, value)
 # first 3 inputs may be overridden by the chain
 # then the remaining 13 are private
] 
type_signal = 0    # accumulator for type hash
value_signal = 0   # accumulator for value / unique hash
pubkey = (0, 0)
for name, (op, args), is_unique in fields:
    value = inputs[name]
    type_signal = H(type_signal, name, op, args[0], args[1], is_unique)
    if is_unique:
        id_signal = H(id_signal, type_signal, value)
    if op == 'either':
        assert value in [args[0], args[1]]
    if op == 'range':
        # Constraint value to a range
        assert value >= args[0] and value <= args[1]
    if op == 'pubkey':
        assert is_on_curve(args[0], args[1])
        pubkey = (args[0], args[1])
    if op == 'verify':
        # Verify the current value signal, using the most recent public key
        assert eddsa_verify(value_signal, pubkey, args[0], args[1])

For example:

Name Op Arg1 Arg2 Unique
topic - my-vote my-vote true
voter pubkey $X $Y true
topping either mushrooms ham true

etc.