, but I do not see any useful information on how to do it, and Libsodium
fails to mention Schnorr.
However we can easily do it with ristretto25519.
[Bernstein explains how to do Schnorr, and briefly visits Schnorr
multisignature.](./multischnorr-20151012.pdf)
# Notation for elliptic curve cryptography
The group operation where one obtains a third elliptic point from two elliptic
points is represented by addition, $A=B+C$, capitals represent members of the
group, (elliptic points, public keys), lower case represents integers modulo
the order of the group (scalars, private keys), and $h()$ is a hash function
that maps an arbitrary stream of arguments of arbitrary type to an integer
modulo the order of the group.
An upper case letter represents the result of multiplying the base point of
the group by the value represented by the lower case letter. Thus if\
$B_{base}$ is the base point then $K=kB_{base}\,$
$h(\cdots)$ is hash function that generates an integer modulo the order of the group (hence our use of $h$ rather than $H$) from an arbitrary stream of arguments of arbitrary type. It is hard to reverse, the only efficient way of reversing it being to guess all possible pre images from which it might be constructed..
# Single Schnorr Signature
Signer secret key is $k$, his public key is $K$
## Sign message with $k$
- Generate an unpredictable $r$ from the message and the secret key. If we ever use the same $r$ with two
different values of $c$, we reveal
our public key, which is why we
make $r$ depend on the same message as we are signing.
we could use some randomness to generate the konce (key used once, single use secret key), but this would mean that we would sign the same thing twice with two different signatures, which in a much signed item, such as a key or a Zooko id, is undesirable.
- Compute $r = h(k,M)$, a per message secret scalar. Or $r$ can be an
unpredictable secret scalar, randomly generated, but we have to make sure it is truly random and never repeated, which is apt to fail because of computer determinism.
- Compute $R$, a per message elliptic point, a Konce, meaning an
elliptic point that can be used only once, never to be reused because
made public.
- Compute $c = h(R,$ Message$)$
- Compute $s = r+c*k\,$\
Note that:\
$S= R+c*K$
signature is $c, s$
## Verify signature
- Check that $c, s$ are valid scalars, which is trivial.
- Check that $K$, the signing public key, is a valid member of the
prime order group, which is not always trivial.
- Compute $R = S − c*K$\
The reason the signer makes $s$ public rather than $S$, is that to prevent a signature from being faked by someone who does not know the secret underlying $S$.
- Check that $c = h(R,$ Message$)$
# Schnorr multisignature
Obvious problem with multisig – you need proof that each putative signer
is able to produce a singlesig, hence no space advantage for konces, which is the major crypto currency use. but for voting on
the Paxos protocol, major advantage, since the singlesig is apt to be
durable and cached, so the signature signifying approval of the
blockchain is single Schnorr signature connected to a possibly large
collection of individual signing keys. To prove the multisig on a new
block is valid, you need to have and have checked a single sig for each
of the signatories, but it does not have to be a new singlesig. It can
be an old cached singlesig, so you don’t need to download and check
each of the singlesigs with each new block. You only need to check a
single signature, assuming you already have old singlesigs.
So, Schnorr multisig, at least in the simple version, presupposes a
large existing data structure with good cryptographic properties,
presumably a Merkle-patricia tree, listing each party entitled to sign,
the self signed signature of that party, and the voting weight and
voting rights of that party, and the hash at the root of that tree is a
Schnorr multisig.
This, of course, occupies slightly more space than the simple tuple of
signatures, but has the advantage that it does not need to change very
often, and usually only a small part of it needs to change, while the
multisig by itself is relatively small.
But it is not that small. For each possible multisig, you have to list
the keys of all the signers, and then look up their rights in the Merkle
patricia tree, which is OK if the members of the board are hiring the
CEO, but is going to suck mightily if the shareholders are electing the
board.
However, chances are in practice, it will commonly be the case that the
same group votes over and over again, so, if space and verification time
is a concern, you can record previous multisigs and their
verification in the Merkle tree, and record the signatures of the latest
signing as a delta on some past signature, and do the verification as a
delta on some past verification.
Suppose you are doing the Paxos protocol, and every consensus block has
to be signed by one hundred peers, every few minutes. Well, you are
still going to have to verify the single sigs of the peers signing the
group signature, which gives you no savings in time or space over simple
tuple of singlesigs. You are still going to have to verify one hundred
peers. But if it is usually the same clique signing each each time, it
will take you very little time or space to prove that this consensus
hash was signed by the same clique as signed the other hundred consensus
hashes, which you verified a long time ago, and do not need to repeat
the verification. Of course their voting rights might have changed, but
if the cliques do not change much, their voting rights probably don’t
change much, so you don’t have to do full verification every single
time.
If the latest sig is compatible with the current and older voting rights,
the sig should reference the older voting rights Merkle-patricia tree of
voting rights, and the peers should validate it on the basis of the
current voting rights, thus validating that the older voting right
suffices. This could produce a false signature and a fork if the voting
rights radically change, and old voters don’t like the change, but in
such a large scale public event, it will be highly visible and detected.
Each client wallet when talking a client wallet on another fork will
discover that its root is out of date. We implement default wallet
behavior to accept the root with the most recent voting rights list, and
of two roots with the same voting rights list, the root most recently
signed.
## Generate Signature
Kevin and Josephine have private keys $k_{Kevin}$ and $k_{Josephine}$, and public
keys $K_{Kevin}$ and $K_{Josephine}$,
and want to generate a multisig to verify to a verifier that both of them signed
- Kevin generates an unpredictable scalar $r_{Kevin}$ which is never
twice the same, is random rather than deterministic as in single sig
(otherwise two multisig signings of the same message will reveal his
private key, since he cannot predict or control $c$)\
Josephine similarly computes $r_{Josephine}\,$
- Kevin shares $R_{Kevin}$ with each of the other
signatories, and they with him.
- Each of the signatories computes $R = R_{Kevin} +R_{Josephine} +\dots$
- Each of the signatories computes $c = h(R,$ Message$)$
- Kevin computes $s_{Kevin}=r_{Kevin} + c*k_{Kevin}$\
Josephine computes $s_{Josephine}=r_{Josephine} + c*k_{Josephine}$, and
We need an IFF ping that can be distibuted to a very large number of people. Which means that the means for identifying it will leak. Which means it has to be possible to generate a thousand variants on the ping, so that if it leaks, the leadership hierarchy can identify the leaker, but no one else can.
If a member of a sub subgroup leaks, then the leader of the group should be able to identify the subgroup that leaked, the leader of the subgroup should be able to identify the sub subgroup that leaked, and the leader of the sub sub group should be able to identify the member that leaked.
For large groups, the ping has to mutually identify the two subgroups to
each other, and also supply information the chain of command could use to
identify the individual, but to a random member of a one subgroup, should
only identify the other party's subgroup.
Let us figure out how to do this in a single level hierarchy, one leader, plus regular members.
Suppose the evil overlord frequently signs a fresh secret key of each
member, and a randomized list of the corresponding public keys get
distributed to every member.
Then a member simply does authentication without signing on his secret key, and sends the sequence number of his secret key. Which is useless information to anyone who does not know the list.
But this method fails to scale to an enormous hierarchical group of groups, because that information is going to leak very fast, and there is no way of
tracing who leaked it.
So we need a ping that the leader can identify as coming from a particular member, but a random member cannot. But a random member _can_ recognize it as coming from _a_ member.
So Bob, who is a member sub-sub-sub-group CAFD, which is a subgroup of sub-sub-group CAF, which is a subgroup of sub-group CA, which is a subgroup of C, wants to know if a mystery target is fellow member of C.
Trouble is, he wants to do so without revealing he is a member of group C
_except_ to a fellow member of group C. But information that could allow
any member of group C to recognize the ping is going to leak. So we need a
multi stage ping, where you don't know who you are talking to until both
parties have revealed a fair bit of zero knowledge proofs of knowledge.
We want both parties to reveal information that the leadership hierarchy
could use to identify both parties, but after they have both revealed that
information, it is meaningless to them, though potentially meaningful to the
leadership, they still do not know whether the other is a member of group C,
until they reveal further information.
So if there is a leak that defeats the IFF, the leadership hierarchy can
track that leak.
If everyone can IFF, everyone can leak data that will enable enemy fake IFF, so neither party can be allowed to id the ping until after both sides have received information that would allow a much smaller group, much less likely to leak, to id the ping.