-
Notifications
You must be signed in to change notification settings - Fork 56
Semaphore Circuit Idea Specification
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.
Register a signal by passing its schema to the smart contract, this will generate a unique ID
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.