b4e3409fea
reliable broadcast channel to atomic broadcast channel Noted that Tokio is a bad idea for async Designed a C api async Noted that my too clever by half sfinae code has been obsolted by concepts.
659 lines
32 KiB
Markdown
659 lines
32 KiB
Markdown
---
|
||
title:
|
||
Multisignature
|
||
# katex
|
||
sidebar: true
|
||
...
|
||
|
||
To do a Schnorr multisignature, you just list all the signatures that
|
||
went into it, and the test key is just adding the all the public keys
|
||
together. Which gives you pretty fast, though totally non anonymous,
|
||
voting, with no need for an elaborate, ingenious, and difficult to
|
||
understand key distribution system.
|
||
|
||
Supposedly [Schnorr multisignature can be done on
|
||
ED25519](https://datatracker.ietf.org/meeting/99/materials/slides-99-cfrg-collective-edwards-curve-digital-signature-algorithm-draft-ford-cfrg-cosi-00-00)
|
||
, 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
|
||
similarly each of the other signatories.\
|
||
$S_{Kevin} = s_{Kevin}*B_{base} = R_{Kevin} + c*K_{Kevin}^{}$
|
||
- Kevin shares $s_{Kevin}$ with each of the other signatories, and they with him
|
||
Each of the signatories computes\
|
||
$s = s_{Kevin} + s_{Josephine} +\dots$\
|
||
(thus Kevin cannot predict or control $s$, thus has to use a random
|
||
rather than deterministic konce)
|
||
- signature is $c, s$
|
||
|
||
## Verify Multsignature
|
||
|
||
- Check that $c, s$ are valid scalars, which is trivial.
|
||
- Check that each of the signing keys is a valid member of the prime
|
||
order group, and a singlesig exists for each signing key of the multisig.
|
||
- $S=s*B_{base}\,$
|
||
- Compute $R = S − c*(K_{Kevin} + K_{Josephine} +\dots )$
|
||
- Check that $c = h(R,$ Message$)$, proving that $S = s*B = R + c*(K_{Kevin}+K_{Josephine}+\dots)$
|
||
|
||
Often the checker does not know nor care whether there are multiple
|
||
co-signers, because the co-signers have already generate an assertion that
|
||
$(K_{Kevin}+K_{Josephine}+\dots)$ is the public key, and hence does not
|
||
have to check the singlesig.
|
||
|
||
If there are quite a few signers, this should be implemented as
|
||
server-client.
|
||
|
||
Each of the clients submits the signing key and a konce (key used once),
|
||
server replies with\
|
||
$K=\sum\limits_{client}K_{client}$, the sum of all signing keys\
|
||
$R=\sum\limits_{client}R_{client}$, the sum of all konces\
|
||
and $c=h(R,$ Message$)$, the value to be signed.\
|
||
Each of the clients checks $c$ and returns $s_{client}$
|
||
Server replies with\
|
||
$s=\sum\limits_{client}s_{client}\,$
|
||
|
||
Each client checks the signature $c, s$
|
||
|
||
For a two party signature, this collapses to a simpler algorithm. Client
|
||
sends his konce. Server returns $s_{server}$, the sum of all signing keys,
|
||
and the sum of all konces.
|
||
Then client computes the signing key, returns it, and the server checks to
|
||
see if it works. Should be a three packet handshake.
|
||
|
||
It is commonly the case that one party is the payee or beneficiary of
|
||
the thing being signed, an the other party does not particularly need or
|
||
want the signature, other than he needs to know it exists for his
|
||
records, and may need to resend the signing secret, accompanied by the
|
||
signing key and the identifier of the thing being signed.
|
||
|
||
In this case, the payee sends the konce (key used once, the single use
|
||
secret), and the payee sends the konce, and does not need
|
||
the beneficiary’s konce, nor the completed signature,
|
||
and treats the transaction as completed, because he has seen the thing
|
||
being signed, and signed it. Doing it the other way around adds an extra
|
||
point of failure.
|
||
|
||
For a large number of parties, you are going to have hold the protocol
|
||
open for a considerable time.
|
||
|
||
For a vast number of parties, you are never going to get everyone to
|
||
complete the protocol all the way through, so have to use threshold
|
||
cryptography, where if everyone gets a enough information, even if they
|
||
do not get all of it, they can calculate the signature.
|
||
|
||
# Threshold Signatures
|
||
|
||
FROST is an algorithm that produces a regular schnorr signature, and allows
|
||
a quite large number of unequal shares.
|
||
|
||
|
||
A threshold signature has the interesting feature that it is a randomness
|
||
beacon. If there is one honest participant party to the signing it generates a
|
||
random value unpredictable to all participants
|
||
|
||
One application: The participants sign off on assertion that their share is such and such, and
|
||
the signature itself controls the random distribution of fractional voting
|
||
shares in the next signature as whole shares, so that voting shares, as
|
||
nearly as possible, approximate ownership shares.
|
||
|
||
This is not in fact a useful discussion of Threshold signatures, so much as a
|
||
list of links. I don’t entirely trust myself to implement threshold
|
||
signatures.
|
||
|
||
Suredbits describes the [FROST algorithm for Schnorr distributed key generation and signing].
|
||
This algorithm is not robust. If any one of the
|
||
participants goes down in the middle you have to start all over, but it is
|
||
clean, simple, and easy to understand.
|
||
|
||
[FROST algorithm for Schnorr distributed key generation and signing]:https://suredbits.com/schnorr-applications-frost/
|
||
"Schnorr Applications: FROST"
|
||
|
||
[FROST with unequal shares]:https://github.com/Trust-Machines/frost
|
||
|
||
Source code for [FROST with unequal shares] is available on github, implemented for the bitcoin elliptic curve.
|
||
|
||
Each of the participants acts as the trusted dealer for his own share, hands
|
||
out shares in it to everyone else, and the final key is the sum of everyone's
|
||
share.
|
||
|
||
This description is easily the most intelligible description of distributed
|
||
key generation and signature generation that I have read, because it is
|
||
adapted to the special case of Schnorr signatures, which have the huge
|
||
advantage of linearity. But, not robust.
|
||
|
||
The practical limit for non robust schemes is about fifty participants. If
|
||
you have a hundred participants it keeps starting over and over again, and
|
||
eventually this causes more and more people to drop out in the middle as
|
||
they lose patience.
|
||
|
||
[Practical Large Scale Distributed Key Generation]:
|
||
./PracticalLargeScaleDistributedKeyGeneration.pdf
|
||
|
||
[Revisiting the Distributed Key Generation for Discrete-Log Based Cryptosystems]:
|
||
./threshold_shnorr.pdf
|
||
|
||
[Practical Large Scale Distributed Key Generation] references
|
||
[Revisiting the Distributed Key Generation for Discrete-Log Based Cryptosystems]
|
||
which references Schnorr signatures.
|
||
|
||
It is a follow up to the (unscalable and arguably inherently centralized)
|
||
[Secure Distributed Key Generation for Discrete-Log Based
|
||
Cryptosystems](./SecureDistributedKeyGeneration.pdf)
|
||
|
||
The basic algorithm is that you generate a distributed key, from which
|
||
a subset of the key recipients can generate a Schnorr signature.
|
||
|
||
[Revisiting the Distributed Key Generation for Discrete-Log Based
|
||
Cryptosystems](./threshold_shnorr.pdf) gives reasonably detailed instructions
|
||
for implementing threshold Schnorr, without any trusted central authority but
|
||
assumes various cryptographic primitives that we do not in fact have, among
|
||
them a total order broadcast channel.
|
||
|
||
## total order broadcast Channel
|
||
|
||
A key cryptographic primitive in threshold signatures, and indeed in almost
|
||
every group cryptographic protocol, is the total order broadcast channel – that
|
||
any participant can reliably send a message that is available to all
|
||
participants.
|
||
|
||
In actual practice we have unreliable point to point two party communications,
|
||
from which we have to construct a broadcast channel.
|
||
|
||
Practical applications of these cryptographic protocols seem to be relying on
|
||
a trusted broadcaster, who is apt to be untrustworthy when there is money,
|
||
power, or valuable secrets lying on the table.
|
||
|
||
Trouble is that in practice, certain messages are likely to be hidden from
|
||
certain participants, and other participants will be unaware that they are
|
||
hidden, or they will receive a discrepant message and incorrectly believe they
|
||
are receiving the same message as others.
|
||
|
||
In a large group, one can assume that more than half the participants are
|
||
honest, so one can construct a broadcast channel using the Paxos protocol.
|
||
|
||
Every distributed cryptographic protocol needs a secure broadcast
|
||
channel, and every blockchain is a secure broadcast channel.
|
||
|
||
One of the requirements of secure total order broadcast channel is that _it
|
||
stays up_. But a secure broadcast channel for a lightning type
|
||
transaction is going to be created and shut down. And if it can be
|
||
legitimately shut down, it can be shut down at exactly the wrong moment
|
||
for some of the participants and exactly the right time for some of the
|
||
participants. Hence the use of a “trusted” broadcast authority, who
|
||
stays up.
|
||
|
||
We could attain the same effect by a hierarchy of secure total order broadcast
|
||
channels, in which a narrow subchannel involving a narrower set of
|
||
participants can be set up on the broader channel, and shutdown, with its
|
||
final shutdown signature available in the broader channel, such that someone
|
||
who has the right code can find on the durable broadcast channel, the signature he needs.
|
||
|
||
But interesting protocols are likely to involve small groups for which we want
|
||
the transaction to fail if any of the participants are defecting.
|
||
|
||
For example, the lightning protocol is cryptographically enforced
|
||
correspondence banking, and an eternal problem in correspondence banking is
|
||
insider check kiting. A shill sends a check to another shill, so that one
|
||
correspondence banker can scam another correspondence banker, so the group
|
||
attempting to organize the transaction is going to consist of two shills, one
|
||
scammer, one pigeon, and one innocent third party roped in to obscure who is
|
||
doing the scamming and who is being scammed, giving a majority of three evil
|
||
participants against two good and trusting participants.
|
||
|
||
By and large, the more money and power that is on the table, the smaller the
|
||
group engaging in the cryptographic protocol is apt to be.
|
||
|
||
We want the transaction to fail in such cases. Generalizing to all
|
||
group cryptographic protocols, we want the broadcast channel to fail and
|
||
to be seen to fail in such cases.
|
||
|
||
The Byzantine Paxos protocol is designed for a large group and is intended to
|
||
keep going permanently in the face of the hardware or software failure of some
|
||
participants, and Byzantine defection by a small conspiracy of participants.
|
||
|
||
For a total order broadcast channel to be reliable, you are relying on it to
|
||
stay up, because if it goes down and stays down, its state for transactions
|
||
near the time it went down cannot be clearly defined.
|
||
|
||
For a total order broadcast channel to be in a well defined state on shutdown,
|
||
it has to have continued broadcasting its final state to anyone interested
|
||
for some considerable time after it reached its final state. So you are
|
||
trusting someone to keep it going and available. In this sense, no group
|
||
cryptographic transaction can be entirely trustless.
|
||
|
||
I intend that the rho blockchain will primarily a notarization system that
|
||
just happens to special case notarizing rhocoin transactions. The notaries
|
||
will be a collection of durable broadcast channels, each one typically
|
||
maintained by a single host, albeit a notarization will not be evidence usable
|
||
on the blockchain until its notary block is Merkle chained by the blockchain.
|
||
If the blockchain automatically trusts notary signatures, they will rapidly
|
||
cease to be trustworthy. The chain, not the signature, makes it officially
|
||
official. The notary signature and rowid is merely a promise to make it
|
||
official. The blockchain will treat notaries as untrusted, so that everyone
|
||
else can treat them as trusted at low risk.
|
||
|
||
## scaling
|
||
|
||
According to [Practical Large Scale Distributed Key Generation](./PracticalLargeScaleDistributedKeyGeneration.pdf) their algorithm is of
|
||
order ${[log (n)]}^3$, meaning it should produce a Schnorr signature for
|
||
thousands of voters with hundreds of thousands of shares, in a a potentially
|
||
decentralized manner, without a trusted dealer, making it useful for digital
|
||
corporations, and capable of electing producing a chain of signatures
|
||
(shareholders sign the board, board signs the CEO, CEO signs every corporate
|
||
officer identity, CEO organizes the election of the board), capable of being
|
||
evaluated by everyone interacting with the business over the net.
|
||
|
||
Obviously the total order broadcast protocol of such a very large scale key
|
||
generation will look more like a regular blockchain, since many entities will
|
||
drop out or fail to complete directly.
|
||
|
||
# [Blind SchnorrSignature.](https://www.math.uni-frankfurt.de/~dmst/teaching/WS2013/Vorlesung/Pointcheval,Stern.pdf)
|
||
|
||
[See also](https://eprint.iacr.org/2019/877.pdf).
|
||
|
||
[and](https://suredbits.com/schnorr-applications-blind-signatures/)
|
||
|
||
Blind Schnorr signatures are vulnerable to the [Wagner attack], which
|
||
can be defeated by refusing to do large numbers of blind signatures in
|
||
parallel, and/or randomly failing to complete some blind signatures.
|
||
|
||
[Wagner attack]:https://www.iacr.org/archive/crypto2002/24420288/24420288.pdf
|
||
|
||
# Regular Elliptic Signature
|
||
|
||
Signer secret scalar $k$. Signer public point $K=k*B$. $B$ is base point.
|
||
|
||
Signature is scalar $s$ and point $R$, such that
|
||
$S = s*B = h(R,$ Message$)*K+ R$
|
||
|
||
## Signing
|
||
|
||
Generate random secret scalar $r$, public point $R=r*B$
|
||
|
||
calculate public scalar $s = h(R$, Message)*k + r$
|
||
|
||
Reveal s and R for message.
|
||
|
||
## [Blind signing using a regular elliptic signature](https://pdfs.semanticscholar.org/e58a/1713858a5b9355a9e18adfe3abfc05de244e.pdf)
|
||
|
||
# Pairing based cryptography
|
||
|
||
In pairing based cryptography the computational Diffie--Hellman problem
|
||
is believed to be infeasible while the simpler decisional
|
||
Diffie--Hellman problem can be easily solved using the pairing function.
|
||
|
||
In a cryptographic group, given $G$, $xG$, and $yG$ it is hard to find
|
||
$xyG$, unless you know $x$ or $y$.
|
||
|
||
In a pairing based group, given $G$, $xG$, $yG$ and $xyG$ you can
|
||
easily *verify* that $xyG$ is correct, even though you are unable to
|
||
calculate the correct value.
|
||
|
||
Pairing based cryptography can do all sorts of really cool things, and I
|
||
am not sure how fast it can do them, but we do not in fact have any
|
||
obvious need for it.
|
||
|
||
## Proposed uses for pairing based crypto
|
||
|
||
We want money payments to operate in private invitation only messaging
|
||
and blog groups, without causing the group to be exposed.
|
||
|
||
We also need pairing based crypto to interface between crypto currency,
|
||
and the corporate form, though threshold signatures. So we have a white
|
||
face, a grey face, and a black face. The white face is the interface
|
||
between crypto cash and to the corporate form that exists both
|
||
cryptographically and on government registries, the grey face is the
|
||
interface to the corporate form that exists only cryptographically, not
|
||
registered with the state (with the result that scams will abound) and
|
||
the black face is secret invitation only blogs and messaging groups,
|
||
within which it is possible to make secret payments.
|
||
|
||
These invitation only blogs and messaging groups will exist with and
|
||
within open searchable blogs and messaging groups, hidden by the secret
|
||
handshake protocol.
|
||
|
||
The structure will be ultimately rooted in [Zooko’s triangle](names/zookos_triangle.html), but normal
|
||
people will most of the time sign in by zero knowledge password
|
||
protocol, your identity will be derivative from someone else’s Zooko
|
||
based identity.
|
||
|
||
Useful links on this topic are “XDH assumption”, “pairing based
|
||
cryptography”, “Bilinear Diffie-Hellman”, and “gap Diffie—Hellman
|
||
(GDH) groups”.
|
||
|
||
A list of libraries now
|
||
[available](https://gist.github.com/artjomb/f2d720010506569d3a39) PBC
|
||
looks like the best. MIRACL uses a strong copyleft license. AGPL: all
|
||
the software linked against free software (free in GNU/FSF sense) is
|
||
also free software and freely available. GNU Public License is the most
|
||
famous of such “strong copyleft” FOSS licenses. The GPL copyleft
|
||
clause triggers when an application is distributed outside of company
|
||
boundaries. And servicing customers from a company server running the
|
||
code constitutes distribution.
|
||
|
||
MIRACL is written in C, and can be used from C, but is designed for C++.
|
||
Comes with inline C++ wrappers.
|
||
|
||
But hell, I like C++. But C++ not going to fly on android. Scala does
|
||
not support Visual Studio, and visual studio does not really support
|
||
android, though it confidently believes that it does.
|
||
|
||
Useful threshold signatures requires pairing based cryptography. And
|
||
pairing based cryptography also needed for useful implementation of the
|
||
secret handshake (green beard, Masonic Lodge) problem. Allegedly good
|
||
for zero knowledge password protocol, though I am pretty sure that
|
||
problem has been solved without using pairing based cryptography.
|
||
|
||
Pairing based cryptography is usually described using the notation that
|
||
the group operation is multiplication, and the one way function
|
||
combining an integer with a member of the group to produce another
|
||
member of the group is exponentiation. But pairing based cryptography is
|
||
easier to understand if we call the group operation addition, whereupon
|
||
we call the application of an integer modulo the order of the group
|
||
multiplication, instead of calling it exponentiation.
|
||
|
||
In pairing based cryptography, the group supports addition (it is
|
||
commutative and associative), and *also supports something like multiplication*
|
||
(it is also commutative and associative), albeit the result of multiplication
|
||
is not a member of the original group, but a member of another group,
|
||
the pair group.
|
||
|
||
That it supports something like multiplication is described as “Bilinear
|
||
Diffie-Hellman”, and if you call it “something like multiplication”
|
||
people who are experts in the field will conclude you are an idiot.
|
||
|
||
So, let us, as usual, use the notation that members of the group are capital
|
||
letters, and integers modulo the order of the group are lower case
|
||
italics. Let us denote members of the pair group, the result of
|
||
multiplying members of the original group with each other, with Greek letters.
|
||
|
||
Which notation allows us to leave out all the academic stuff about $\forall P \in
|
||
G$. If it is a regular capital, it stands for any member of $G$, unless
|
||
otherwise specified. In proper academic language (apart from the fact
|
||
that I am leaving out all the $\forall P \in G$ stuff):
|
||
|
||
Let G be an cyclic group of prime order written additively and $ϓ$
|
||
another cyclic group of the same order written multiplicatively. A pairing is
|
||
a map: $e : G × G → ϓ$ , which satisfies the following properties:
|
||
|
||
- Bilinearity: $\forall a, b, P, Q : e(aP, bQ) = e(P, Q)^{ab}$
|
||
(notice that the left hand side of the equals sign is written
|
||
additively, and the right hand side written multiplicatively)
|
||
- Non-degeneracy: e ≠ 1
|
||
- Computability: there exists an efficient algorithm to compute e
|
||
|
||
Whereupon in this notation:
|
||
$B_{base}$, the base point, is widely known, Ann’s private key is $a$, her public key is $A = aB_{base}$
|
||
|
||
In C++ is is useful to represent both groups additively, allowing the
|
||
operation of the addition of any member of either group to another
|
||
member of the same group, the multiplication of any member of either
|
||
group by an integer, producing another member of the same group, and the
|
||
operation e(P,Q), where P and Q are members of the first group, as infix
|
||
multiplication producing a member of the second group.
|
||
|
||
In this notation the magic equality becomes
|
||
|
||
Bilinearity: $\forall a, b, P, Q :$
|
||
$(a*P)*(b*Q) == (a*b)*(P*Q)$
|
||
|
||
Requiring us, in C++, to create an infix multiplication operator for the
|
||
mapping, an infix addition operator for each group, and an infix
|
||
multiplication by integer operator for each group.
|
||
|
||
To sign a document with the secret key $a$, publish $M = $ah($Message$)B$
|
||
|
||
To test the signature, check that
|
||
|
||
$A*(h(Message)B_{base})=B_{base}*M$
|
||
|
||
Which it should because
|
||
|
||
$(a*B_{base})*(h($
|
||
Message
|
||
$)*B_{base}) =B_{base}*(a*h($
|
||
Message
|
||
$)*B_{base})$ by bilinearity.
|
||
|
||
The threshold variant of this scheme is called GDH threshold signature
|
||
scheme, Gap Diffie Hellman threshold signature scheme.
|
||
|
||
This scheme is also good for blind signatures, because if you sign an
|
||
arbitrary point of the group, which the person asking for the signature
|
||
knows is sum of an already signed point of the group, multiplied by a
|
||
random secret, plus the thing he actually wants signed, he can then
|
||
subtract the two signed quantities to find a third signed quantity,
|
||
corresponding to a well formed token, that token unknown to the signer.
|
||
|
||
## Secret Handshakes
|
||
|
||
[Paraphrasing](./secret_handshakes.pdf)
|
||
|
||
We can prove, without revealing, shared knowledge of the master secret of
|
||
the secret society, without third parties cluing it, using ordinary
|
||
elliptic curve cryptography.
|
||
|
||
Trouble is that this requires wide sharing of the secret, which is thus unlikely to remain very secret for very long.
|
||
|
||
The Secret society of evil has a frequently changing secret key
|
||
$k_{evil}$ Ann has a secret key $k_{Ann}$ and public key $K_{Ann} =
|
||
k_{Ann}B$, Bob has a secret key $k_{Bob}$ and public key $K_{Bob} =
|
||
b_{Bob}B$
|
||
|
||
Let $h(…)$ represent a hash of the serialized arguments of H, which
|
||
hash is an integer modulo the order of the group. Let $H(…) = h(…)B$.
|
||
|
||
The evil overlord of the evil society of evil issues Ann and Bob a
|
||
signed hash of their public keys. For Ann, the signature is
|
||
$k_{evil}H($“Ann”, $K_{Ann},$ “evil secret society of evil”$)$, similarly for Bob
|
||
|
||
The problem is that Ann does not know whether Bob is also a member of
|
||
the secret society of evil, and wants to send him a message that is only
|
||
going to be intelligible to him if he secretly has a key signed by the
|
||
secret society of evil, but is not going to be recognizable to third
|
||
parties as signed by the secret society of evil.
|
||
|
||
So, they use as part of their shared secret whereby they encrypt
|
||
messages, the secret that Ann can calculate:\
|
||
$[k_{evil}H($“Ann”,
|
||
$K_{Ann},$ “evil secret society of evil”$)]*H($“Bob”, $K_{Bob},$ “evil
|
||
secret society of evil”$)$
|
||
|
||
Bob calculates:\
|
||
$H($“Ann”, $K_{Ann},$ “evil secret society of evil”$)
|
||
*[k_{evil}H($“Bob”, $K_{Bob},$ “evil secret society of evil”$)]$
|
||
|
||
Thus proving possession of their evil keys to each other without
|
||
revealing them to each other, and without revealing that possession to
|
||
someone who does not have the expected evil key.
|
||
|
||
Overly complicated and excessively clever. In practice, if you have a
|
||
secret society, you have a secret chatroom, in which case the routing
|
||
metadata on messages going to and from the chatroom are traceable if
|
||
they pass through enemy networks.
|
||
|
||
# IFF
|
||
|
||
But suppose you want battlespace iff (Identify Friend or Foe). You want to
|
||
send a message directly to an unknown target that will identify as friendly
|
||
if the other guy is a friendly, but not necessarily let him know enemy if he
|
||
is enemy. If he already knows you are enemy, you don’t want to give him
|
||
the means to identify enemy iff from your friends.
|
||
|
||
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.
|