mirror of
https://github.com/monero-project/research-lab.git
synced 2024-12-23 12:09:58 +00:00
442 lines
22 KiB
Text
442 lines
22 KiB
Text
|
BOOTLE-RUFFING RINGCT SCHEME
|
||
|
----------------------------
|
||
|
Sublinear-sized ring signatures without trusted
|
||
|
set-ups or bilinear pairings. Summarized for
|
||
|
Monero Research Lab by B Goodell
|
||
|
|
||
|
We describe sublinear-sized ring signatures for use in cryptocurrency. This
|
||
|
scheme was first sent to MRL by Ruffing and co-authors. These results use
|
||
|
tools first described by Bootle, et al in the paper "Short Accountable Ring
|
||
|
Signatures Based on DDH," 2015 European Symposium on Research in Computer Sec-
|
||
|
urity, use a "vanilla" elliptic curve multisignature scheme first described by
|
||
|
Bellare and Neven in "Multi-signatures in the plain public-key model and a gen-\
|
||
|
eral forking lemma," 2006 Proceedings of the 13th, ACM conference on Computer and
|
||
|
Communications Security.
|
||
|
|
||
|
This is a living document and will be updated. In section I, the introduction,
|
||
|
we introduce the general idea of the scheme together with preliminary stuff.
|
||
|
We have a section on homomorphic commitments and encryption, a section on
|
||
|
ordinary multi-signatures, and a section on the NIZK proof systems presented
|
||
|
by Bootle et al. In section II, we present pseudocode describing Ruffing's
|
||
|
scheme. In section III, references.
|
||
|
|
||
|
I. INTRODUCTION
|
||
|
|
||
|
The scheme presented by Ruffing roughly works as follows, exploiting homo-
|
||
|
morphic commitments. Sender Sally uses L of her txnout keys to send some amount
|
||
|
stored in a commitment to receiver Roy. Sally wishes to implicate N-1 other
|
||
|
senders, so she constructs an LxN matrix of public keys (L = # key images used,
|
||
|
N = ring size) by picking random public keys from the anonymity set; she stores
|
||
|
her own pubkeys in some secret column i*. Sally demonstrates that the output
|
||
|
amount from her secret column and the input amount are the same without re-
|
||
|
vealing that column or the amounts by using a NIZK proof from the Bootle paper
|
||
|
to show that at least one commitment in a vector opens to zero. In the constru-
|
||
|
ction of this proof, she uses information from her secret keys, which binds the
|
||
|
index she can open to zero to the column of pubkeys in the matrix without re-
|
||
|
vealing which index. She uses her secret keys to construct a multisignature on
|
||
|
the Bootle proof that is verifiable with the key images only. This way, her
|
||
|
signature consists of some random information, a Bootle proof, and a multi-
|
||
|
signature on the Bootle proof. The multisignature is efficient in construction,
|
||
|
verification, and storage. The Bootle proof, for a vector of commitments of
|
||
|
length N = n^m, takes O(n*m) (roughly) for construction, verification, and sto-
|
||
|
rage. For a ring size N=n^m, for a fixed ring base n (say all ring sizes are
|
||
|
powers of n=16), the Ruffing scheme is approximately log(N).
|
||
|
|
||
|
The scheme consists of four algorithms, KEYGEN, SPEND, and VER, which we des-
|
||
|
cribe in the next section. The scheme uses multisignatures and Bootle proofs
|
||
|
as subroutines, and hammers on homomorphic commitment very hard, so we describe
|
||
|
these in this section as "pre-requisites". The Bootle method is an interactive
|
||
|
sigma protocol that uses another interactive sigma protocol as a subroutine. We
|
||
|
made these both non-interactive and present the pseudocode in PROVE1, VALID1,
|
||
|
PROVE2, VALID2 (the Ruffing scheme uses PROVE2, VALID2, which use PROVE1,
|
||
|
VALID1). The Ruffing scheme did not specify a multisignature scheme; we desc-
|
||
|
ribe here the pseudocode for the Bellare-Neven multisignature scheme, KEYGEN*,
|
||
|
SIG*, VER*.
|
||
|
|
||
|
a. Commitments and Encryption
|
||
|
|
||
|
To commit to a scalar x with some random mask r, we use the following options:
|
||
|
|
||
|
COMp(x; r) := rG + xHp(xG) # Unconditionally hiding Pedersen
|
||
|
COMeg(x; r) := (rG + xHp(xG), rG) # Computationally hiding El Gamal
|
||
|
|
||
|
We may extend these to a vector/array/matrix B=[b[j][i]; j=0...m-1,i=0..n-1]:
|
||
|
|
||
|
COMp(B; r) := rG + b[0][0]Hp(b[0][0]G) + ... + b[m-1][n-1]Hp(b[m-1][n-1]G)
|
||
|
|
||
|
and we can similarly lift this to an El Gamal commitment by appending rG. In
|
||
|
the first case, we refer to x or the matrix B as the "data under commitment"
|
||
|
and the value r as the "mask." Given a Pedersen commitment c, we open c by
|
||
|
revealing x and r, where a verifier checks that c == rG + xHp(xG). Given an
|
||
|
El Gamal commitment (C1, C2), we open by revealing r and x, a verifier
|
||
|
computes C2' = rG, C1' = rG + xHp(xG) from these, and lastly checks that
|
||
|
C1 == C1' and C2 == C2'.
|
||
|
|
||
|
These commitments are additive under the following definition:
|
||
|
|
||
|
COMp(x; r) + COMp(x'; r') := COMp(x+x'; r+r')
|
||
|
COMeg(x; r) + COMeg(x'; r') := COMeg(x+x'; r+r')
|
||
|
|
||
|
|
||
|
b. Ordinary Multi-signature
|
||
|
|
||
|
The Ruffing scheme utilizes as a subroutine an efficient multisignature scheme,
|
||
|
consisting of three algorithms (KEYGEN*, SIG*, VER*). We present a scheme based
|
||
|
on the scheme described by Bellare and Neven in 2006 [3] (which is, in turn,
|
||
|
based on Schnorr signatures). Our variation of the B&N scheme is that it is
|
||
|
executed only by one party holding all the keys, so interaction is unnecessary.
|
||
|
We use a group of prime order q. Ruffing's scheme assumes that the Decisional
|
||
|
Diffie-Hellman assumption holds, so there is no harm in making this assumption
|
||
|
for the ordinary multi-signature scheme. Let G be a commonly known generator of
|
||
|
the group. Let Hs be a hash function that produces a scalar in Zq. Let Zq denote
|
||
|
the integers modulo q.
|
||
|
|
||
|
KEYGEN*: Each user selects x at random from Zq. The secret key is x. The
|
||
|
public key is X=xG. Output (sk,pk) = (x,X).
|
||
|
|
||
|
SIG*: Take as input a message M and a list of private keys L = x[0], x[1],
|
||
|
..., x[n-1]. Let L' be the associated list of public keys X[0], ..., X[n-1],
|
||
|
and assume L' is lexicographically ordered.
|
||
|
1) Compute L* = H(L').
|
||
|
2) For each i=0,1,...,n-1, select r[i] at random from Zq.
|
||
|
3) Compute r=r[0]+r[1]+...+r[n-1] and R=rG.
|
||
|
4) For each i=0,1,...,n-1:
|
||
|
i) Compute c[i] := Hs(X[i], R, L*, M)
|
||
|
ii) Compute s[i] := r[i] + x[i]*c[i]
|
||
|
5) Compute s = s[0] + ... + s[n-1].
|
||
|
6) Output the signature sigma = (R, s)
|
||
|
|
||
|
VER*: Take as input a message M, a set of keys L' = X[0], ..., X[n-1], and a
|
||
|
signature sigma = (R,s).
|
||
|
1) Compute L* = H(L')
|
||
|
2) For each i=0,1,...,n-1, compute c[i] = Hs(X[i], R, L*, M)
|
||
|
3) Accept if and only if sG = R + c[0]*X[0] + ... + c[n-1]*X[n-1]
|
||
|
|
||
|
c. NIZK Proofs
|
||
|
====|====|====|====|====|====|====|====|====|====|====|====|====|====|====|====
|
||
|
Lastly, the scheme also utilizes the following algorithms, (PROVE1, VALID1),
|
||
|
and (PROVE2, VALID2), which are NIZK prove-and-verify algorithm pairs. These
|
||
|
use the Fiat-Shamir transformation to make the zero-knowledge sigma protocols
|
||
|
presented by Bootle non-interactive under the random oracle model. The second
|
||
|
algorithm requires the usage of a helper algorithm, COEFs, which computes
|
||
|
coefficients of certain polynomials.
|
||
|
|
||
|
The pair (PROVE1, VALID1) allows a prover to demonstrate that each row of a
|
||
|
matrix is a set of commitments to bits that open to exactly one 1 (the rest
|
||
|
open to 0). The implementation works like this:
|
||
|
|
||
|
PROVE1: Take as input ([[b[0][0], b[0][1], ..., b[m-1][n-1]] ], r).
|
||
|
1) Select r[A], r[C], r[D] at random from Zq.
|
||
|
2) For each j=0, 1,..., m-1 and for each i=1,2,...,n-1, select a[j][i]
|
||
|
from Zq at random.
|
||
|
3) For each j, compute a[j][0] = -a[j][1] - a[j][2] - ... - a[j][n-1].
|
||
|
4) Compute A:=COMp(a[0][0], ..., a[m-1][n-1]; r[A])
|
||
|
5) For each j=0,...,m-1 and i=0,...,n-1, compute the values
|
||
|
c[j][i] := a[j][i]*(1-2*b[j][i])
|
||
|
d[j][i] := -a[j][i]^2
|
||
|
6) Compute the commitments C:=COMp(c[0][0], ..., c[m-1][n-1]; r[C]) and
|
||
|
D:=COMp(d[0][0],...,d[m-1][n-1]; r[D]).
|
||
|
7) Compute x := Hs(A,C,D)
|
||
|
8) For each j=0,...,m-1, i=0,...,n-1, compute f[j][i]:=b[j][i]*x + a[j][i]
|
||
|
9) Compute z[A]:= r*x + r[A], z[C]:=r[C]*x+r[D]
|
||
|
10) Output proof P:=A,C,D, f[0][1],f[0][2], ..., f[0][n-1], f[1][1],
|
||
|
f[1][2], ..., f[1][n-1], ..., f[m-1][1], ..., f[m-1][n-1], z[A], z[C].
|
||
|
|
||
|
When PROVE1 is run as a subroutine for PROVE2, the prover will also output the
|
||
|
values of each a[j][i]; these are not part of the formal proof, but they are
|
||
|
used elsewhere. Note that we do not output the first column of the matrix F
|
||
|
whose (ji)^th entry is f[j][i]. Essentially here, we are taking a matrix, we
|
||
|
are showing each row sums to 1 and each element satisfies the equation
|
||
|
b[j][i]*(1-b[j][i]) = 0.
|
||
|
|
||
|
VALID1: Take as input B (the prover wishes to demonstrate B is a commitment to
|
||
|
the values b[j][i] as described in PROVE1) and proof P.
|
||
|
1) If A,B,C,D are each elliptic curve points, both z[A] and z[C] are ele-
|
||
|
ments of Zq, and each f[j][i] are elements of Zq, compute the value
|
||
|
x := Hs(A,C,D). Else, output FAIL and terminate.
|
||
|
2) For each j=0, ..., m-1, compute f[j][0] = x-f[j][1] - ... - f[j][n-1].
|
||
|
3) For each j=0, ..., m-1, i=0,...,n-1, compute each of the values
|
||
|
f'[j][i] := f[j][i]*(x-f[j][i])
|
||
|
4) Return 1 if and only if all of the conditions hold true:
|
||
|
i) For each j=0, ..., m-1, f[j][0]=x-f[j][1]-f[j][2]- ... -f[j][n-1]
|
||
|
ii) xB + A = COMp(f[0][0], ..., f[m-1][n-1]; z[A])
|
||
|
iii) xC + D = COMp(f'[0][0], ..., f'[m-1][n-1]; z[C])
|
||
|
(otherwise return 0).
|
||
|
|
||
|
The pair (PROVE2, VALID2) allows a prover to demonstrate that a sequence of
|
||
|
commitments contains at least one commitment to 1. The implementation works
|
||
|
like this:
|
||
|
|
||
|
PROVE2: Take as input a sequence of values c[0], c[1], ... c[N-1] for
|
||
|
some N= n^m, a secret index i* in this list corresponding to a commitment that
|
||
|
opens to 1, and a random scalar r in Zq. For all integers j, i, define the
|
||
|
Kronecker delta function as DELTA(j,i) := 1 if j=i and 0 otherwise.
|
||
|
1) For k=0, 1, ..., m-1, select random coefficient u[k] at random from Zq.
|
||
|
2) Select r[B] at random from Zq.
|
||
|
3) Write i* in n-ary i* = i*[0] + i*[1]*(n) + i*[2]*(n^2) + ...
|
||
|
... + i*[m-1]*(n^(m-1)), and represent i* as the sequence i*[j].
|
||
|
4) For each j=0, 1, ..., m-1 and i=0, 1, ..., n-1, define the values
|
||
|
d[j][i] := DELTA(i*[j],i).
|
||
|
5) Compute B:=COMp(d[0][0], ..., d[m-1][n-1]; r[B]).
|
||
|
6) Prover runs PROVE1 and stores the output as the list of data
|
||
|
P <- PROVE1(B, (d[0][0], ..., d[m-1][n-1], r[B])) and stores the values
|
||
|
a[j][i] for use in the next step. Note the prover receives A, C, D from
|
||
|
PROVE1, all the values f[j][i], and the values z[A], z[C].
|
||
|
7) coefs <- COEFS(a[0][0], ..., a[m-1][n-1], i*)
|
||
|
8) For k=0, ..., m-1:
|
||
|
i) G[k] := ENCeg(0, u[k]) # = (rHp(G), rG)
|
||
|
ii) For i=0, ..., N-1, update G[k] by multiplying:
|
||
|
G[k]=G[k]*(co[i]^coefs[i][k])
|
||
|
=(G[k][1]+coefs[i][k]*co[i][1], G[k][2]+coefs[i][k]*co[i][2])
|
||
|
The final value for each G[k] from step 8 can be written explicitly:
|
||
|
G[k]=(rHp(G)+coefs[0][k]*co[0][1] + ... +coefs[n-1][k]*co[n-1][1],
|
||
|
rG+coefs[0][k]*co[0][2] + ... +coefs[n-1][k]*co[n-1][2])
|
||
|
9) Compute x' = Hs(A,B,C,D, G[0], ..., G[m-1]).
|
||
|
10) Compute z:= r*(x')^m - u[m-1]*(x')^(m-1) - ... - u[1]*(x')^1 - u[0]
|
||
|
11) Output proof P':=P, B, G[0], ..., G[m-1], z.
|
||
|
|
||
|
VALID2: Take as input a list of N El Gamal commitments co[0], ..., co[N-1] and a
|
||
|
proof P' parsed as P, B, G[0],...,G[m-1], where P is a proof parsed as
|
||
|
P = A,C,D, f[0][1],f[0][2], ..., f[m-1][n-1], z[A], z[C].
|
||
|
1) If A,B,C,D, each G[k] are all elliptic curve points, and if z[A], z[C],
|
||
|
and z are elements of Zq, and if each f[j][i] are elements of Zq, and
|
||
|
if VALID1(B,P)=1, then compute the value
|
||
|
x' := Hs(A, B, C,D,G[0],...,G[m-1]).
|
||
|
Else, output FAIL and terminate.
|
||
|
2) Compute c := ENCeg(0,z).
|
||
|
3) For each k=0,...,m-1, compute
|
||
|
G[k]^(-x^k) := (-x^k*G[k][1],-x^k*G[k][2]).
|
||
|
4) Compute (G[0]^(-(x')^0))*(G[1]^(-(x')^1))*...*(G[m-1]^(-(x')^(m-1))
|
||
|
which explicitly is the ordered pair (G*[1], G*[2]):
|
||
|
(-G[0][1] - (x')G[1][1] - ... - (x')^(m-1)G[m-1][1],
|
||
|
-G[0][2] - (x')G[1][2] - ... - (x')^(m-1)G[m-1][2] )
|
||
|
5) For each j=0, ..., m-1, i=0,...,n-1, compute each of the values
|
||
|
f[j][0] := x' - f[j][1] - f[j][2] - ... - f[j][n-1].
|
||
|
6) For each i=0,...,N-1, write i in n-ary arithmetic as usual as
|
||
|
i = i[0] + i[1]*n + i[2]*(n^2) + ... + i[m-1]*(n^(m-1)). Compute the
|
||
|
values g[i] := f[0][i[0]]*f[1][i[1]]*...*f[m-1][i[m-1] and the
|
||
|
commitments co*[i] := co[i]^g[i] = (g[i]*co[i][1], g[i]*co[i][2]).
|
||
|
7) Compute (co*[0])*(co*[1])*...*(co*[N-1]) which ends up as the ordered
|
||
|
pair (c**[1], c**[2])
|
||
|
(c*[0][1] + c*[1][1] + ... c*[N-1][1], c*[0][2] + ... c*[N-1][2])
|
||
|
8) Compute c'=(c**[1],c**[2])*(G*[1],G*[2])=(c**[1]+G*[1], c**[2] + G*[2]).
|
||
|
9) Return 1 if and only if c' == c and 0 otherwise.
|
||
|
|
||
|
COEFS: We split this into two algorithms. The outer layer, COEFS, is specific
|
||
|
to the Ruffing scheme. The inner layer, COEFPROD, takes two sequences of coef-
|
||
|
ficients as input, representing polynomials, and outputs a sequence of coef-
|
||
|
ficients of the resulting product of those two polynomials. We denote the
|
||
|
Discrete Fourier Transform as DFT, and the inverse IDFT.
|
||
|
|
||
|
COEFS takes as input a matrix A = a[0][0], ..., a[m-1][n-1] and index i* such
|
||
|
that 0 <= i* < n^m. We decompose 0 <= i* < N into the n-ary representation
|
||
|
i* = i*[0] + i*[1]*n + ... + i*[m-1]*n^(m-1)
|
||
|
In this decomposition, for each 0 <= j < m, we have the constraint
|
||
|
0 <= i*[j] < n (otherwise we could include the "runoff" above n into the co-
|
||
|
efficient one index higher). For index 0 <= k < N we again decompose into
|
||
|
the n-ary representation
|
||
|
k = k[0] + k[1]*n + ... + k[m-1]*n^(m-1)
|
||
|
where for each index 0 <= j < m (where N=n^m), we have 0 <= k[j] < n. We rep-
|
||
|
resent the polynomial defined by DELTA(i*[j],k[j])*x + a[j][k[j]] as an array
|
||
|
q[j][k] = [a[j][k[j]], DELTA(i*[j],k[j])]
|
||
|
We then do the following:
|
||
|
1) For each k = 0, ..., N-1:
|
||
|
i) Compute coefList[k] : = q[0][k]
|
||
|
ii) For 1<=j<m update coefList[k] = COEFPROD(coefList[k], q[j][k[j]])
|
||
|
2) Output coefList[0], coefList[1], ..., coefList[N-1].
|
||
|
|
||
|
COEFPROD: Take as input lists c[0],...,c[n-1] and d[0],...,d[n-1]. If these are
|
||
|
not the same length, the shorter one may be padded with zeros at the end. We
|
||
|
can parse the polynomial p(x) = c[0] + c[1]*x + ... + c[n-1]*x^(n-1) and the
|
||
|
polynomial q(x) = d[0] + d[1]*x + ... + d[n-1]*x^(n-1). Let m = 2n-1.
|
||
|
1) Compute P := DFT(p), Q := DFT(q). Both P and Q should have length m and
|
||
|
This should take O(n*log(n)) time.
|
||
|
2) Compute PQ := [P[0]*Q[0], P[1]*Q[1], ...]. This should take O(n) time.
|
||
|
3) Compute t:= IDFT(PQ) = t[0], t[1], ..., t[m]. This should take
|
||
|
O(n*log(n)).
|
||
|
4) Output t as the coefficients of p(x)*q(x).
|
||
|
|
||
|
|
||
|
II. BOOTLE-RUFFING RINGCT SCHEME
|
||
|
|
||
|
We are now in a position to present Ruffing's scheme in its entirety. We select
|
||
|
a group of prime order q under which the Decisional Diffie-Hellman assumption
|
||
|
holds. Let G be a commonly known generator of the group. Let Hp be a hash func-
|
||
|
tion that produces an elliptic curve point. Let Hs be a hash function that prod-
|
||
|
uces a scalar in Zq. Let Zq denote the integers modulo q.
|
||
|
|
||
|
KEYGEN:
|
||
|
1) Select r,r' randomly from Zq.
|
||
|
2) Set sk := (r,r')
|
||
|
3) Set ki := r'G
|
||
|
4) Set pk := ENCeg(ki,r)
|
||
|
5) Output (sk,ki,pk).
|
||
|
|
||
|
SPEND: Take as input an (L x N) matrix of public keys PK written as
|
||
|
PK = [pk[j][i]; j=0,1,...,L-1, i=0,1,...,N-1], such that the signer knows the
|
||
|
associated secret keys of the column with (secret) index i*, a commitment for
|
||
|
each column co = co[0], co[1], ...., co[N-1] such that co[i*] opens to zero, a
|
||
|
set of secret keys sk = sk[0],sk[1],...,sk[L-1], a set of key images ki, a
|
||
|
message M, and a random scalar s from Zq. Write each secret key as
|
||
|
sk[i]=(r[i],r'[i]).
|
||
|
|
||
|
1) Compute co' := sG.
|
||
|
2) Set f := (ki, PK, co, co', M)
|
||
|
3) Compute (c, f') := SUB(f)
|
||
|
4) Compute s' := s + r[0]*f'[0] + r[1]*f'[1] + ... + r[L-1]*f'[L-1]
|
||
|
5) Compute sigma[1] := PROVE2(c, i*,s')
|
||
|
6) Compute sigma[2] := SIG*((r'[0], r'[1], ..., r'[L-1]), (sigma[1], f))
|
||
|
7) Output signature = (co', sigma[1], sigma[2])
|
||
|
|
||
|
SUB: Take as input key images ki = ki[0], ki[1], ..., ki[L-1], a matrix of
|
||
|
public keys PK = [pk[j][i]; j=1,2,...,L, i=1,2,...,N], a set of Pedersen com-
|
||
|
mitments co = co[1], ..., co[N], an elliptic curve point co', and message M.
|
||
|
|
||
|
1) For j=0, 1, ..., L-1:
|
||
|
i) Compute pkz[j] := (ki[j],0)
|
||
|
ii) Compute f[j] := Hs(ki[j],f,j)
|
||
|
2) For i=0, 1, ..., N-1 do:
|
||
|
i) Set c[i] := (co[i], co')
|
||
|
ii) For j=0,1, ..., L-1, update c[i] = c[i]*(pk[j][i]/pkz[j])^(f[j])
|
||
|
3) Output (c,f) where c = c[0], ..., c[N-1], f=f[0], ..., f[L-1].
|
||
|
|
||
|
Note that due to commitment arithmetic the result c[i] is written explicitly as:
|
||
|
(co[i]+f[0]*(pk[0][i][1]-pkz[0][1])+ ... +f[L-1]*(pk[L-1][i][1]-pkz[L-1][1]),
|
||
|
co'+f[0]*(pk[0][i][2]-pkz[0][2])+ ... +f[L-1]*(pk[L-1][i][2]-pkz[L-1][2]))
|
||
|
|
||
|
VER: This verifies a ring signature. Take as input a set of key images
|
||
|
ki = ki[0], ki[1], ..., ki[L-1], a matrix of public keys PK, commitments
|
||
|
co = co[0], ..., co[N-1], an elliptic curve point co', a message M, and a sig-
|
||
|
nature from SPEND, signature = (co', sigma[1], sigma[2]).
|
||
|
|
||
|
1) Set f := (ki, PK, co, co', M).
|
||
|
2) Compute (c, f') := SUB(f) (we only use c for verification)
|
||
|
3) Return 1 iff
|
||
|
(i) the signature sigma[2] on message (sigma[1], f) passes VER* with
|
||
|
keys ki, i.e. VER*((sigma[1],f), ki, sigma[2])==1
|
||
|
(ii) the proof sigma[1] is a valid NIZK proof that one of the commit-
|
||
|
ments in co open to 0, i.e. VALID2(sigma[1], co) == 1.
|
||
|
Return 0 otherwise.
|
||
|
|
||
|
III. Specific Example
|
||
|
|
||
|
Here is a quick concrete example using integer scalars of the Bootle NIZK
|
||
|
proof that a commitment opens appropriately* as in PROVE1/VALID1 above.
|
||
|
We start with random data we wish to commit to. Each entry must be
|
||
|
a bit and each row must sum to 1 if VALID1 is to validate the proof. We
|
||
|
may as well go with the identity matrix:
|
||
|
|
||
|
[ [b[0][0], b[0][1] ], = [ [1, 0],
|
||
|
[b[1][0], b[1][1] ] ] [0, 1] ]
|
||
|
|
||
|
We compute the commitment B = COMp([b[j][i]], rB):
|
||
|
|
||
|
B = rB*G + 1*H[0,0] + 0*H[0,1] + 0*H[1,0] + 1*H[1,1]
|
||
|
|
||
|
We pick random a[0][1], say 7, and a random a[1][1], say -5. We compute a[j][0]
|
||
|
as -sum(a[j][i]):
|
||
|
|
||
|
[ [a[0][0], a[0][1] ], = [ [-7, 7],
|
||
|
[a[1][0], a[1][1] ] ] [ 5, -5] ]
|
||
|
|
||
|
We compute commitment A = COMp( [a[j][i]], rA):
|
||
|
|
||
|
A = rA*G - 7*H[0,0] + 7*H[0,1] + 5*H[1,0] - 5*H[1,1]
|
||
|
|
||
|
We compute c[j][i] = a[j][i]*(1-2b[j][i]), d[j][i] = -a[j][i]^2:
|
||
|
|
||
|
[ [c[0][0], c[0][1] ], = [ [7, 7],
|
||
|
[c[1][0], c[1][1] ] ] [5, 5] ]
|
||
|
|
||
|
[ [d[0][0], d[0][1] ], = [ [-49, -49],
|
||
|
[d[1][0], d[1][1] ] ] [-25, -25] ]
|
||
|
|
||
|
We compute commitments C and D:
|
||
|
|
||
|
C = rC*G + 7*H[0,0] + 7*H[0,1] + 5*H[1,0] + 5*H[1,1]
|
||
|
D = rD*G - 49*H[0,0] - 49*H[0,1] - 25*H[1,0] - 25*H[1,1]
|
||
|
|
||
|
We compute x = Hs(A,C,D). We compute f[j][i] = b[j][i]*x + a[j][i]:
|
||
|
|
||
|
[ [f[0][0], f[0][1] ], = [ [x-7, 7],
|
||
|
[f[1][0], f[1][1] ] ] [ 5, x-5] ]
|
||
|
|
||
|
We compute zA = rB*x + rA, zC = rC*x + rD and send [A,B,C,D, zA, zC] together
|
||
|
with all columns except the first column of [f[j][i]] as our NIZK proof that B
|
||
|
is a well-formed Bootle commitment*. Now a verifier receives the left hand side
|
||
|
of the following system of equations
|
||
|
|
||
|
A = rA*G - 7*H[0,0] + 7*H[0,1] + 5*H[1,0] - 5*H[1,1]
|
||
|
B = rB*G + 1*H[0,0] + 0*H[0,1] + 0*H[1,0] + 1*H[1,1]
|
||
|
C = rC*G + 7*H[0,0] + 7*H[0,1] + 5*H[1,0] + 5*H[1,1]
|
||
|
D = rD*G - 49*H[0,0] - 49*H[0,1] - 25*H[1,0] - 25*H[1,1]
|
||
|
f[0][1] = 7
|
||
|
f[1][1] = x-5
|
||
|
zA = rB*x + rA
|
||
|
zC = rC*x + rD
|
||
|
|
||
|
Using the left hand side only, the verifier computes:
|
||
|
x := H(A,C,D)
|
||
|
f[0][0] := x - f[0][1]
|
||
|
f[1][0] := x - f[1][1]
|
||
|
Now the verifier computes the matrix [f'[j][i]] = [f[j][i]*(x-f[j][i])]:
|
||
|
[ [f'[0][0], f'[0][1] ], = [ [f[0][0]*(x-f[0][0]), f[0][1]*(x-f[0][1])],
|
||
|
[f'[1][0], f'[1][1] ] ] [ f[1][0]*(x-f[1][0]), f[1][1]*(x-f[1][1])] ]
|
||
|
and computes the commitments COM(f[j][i], zA), COM(f'[j][i], zC):
|
||
|
|
||
|
COM( f[j][i], zA) := zA*G + f[0][0]*H[0,0] + f[0][1]*H[0,1] + ...
|
||
|
COM(f'[j][i], zC) := zC*G + f'[0][0]*H[0,0] + f'[0][1]*H[0,1] + ...
|
||
|
|
||
|
The verifier can now check whether
|
||
|
i) xB + A =? COM(f[j][i], zA)
|
||
|
ii) xC + D =? COM(f'[j][i], zC)
|
||
|
|
||
|
Note that if the verifier received the values as specified above, she computes
|
||
|
the same f[0][0], f[1][0] as the prover used, x-7 and 5, so the verifier
|
||
|
obtains the matrix
|
||
|
|
||
|
[ [f[0][0], f[0][1] ], = [ [x-7, 7],
|
||
|
[f[1][0], f[1][1] ] ] [ 5, x-5] ]
|
||
|
|
||
|
and computes
|
||
|
|
||
|
[ [f'[0][0], f'[0][1] ], = [ [7(x-7), 7(x-7)],
|
||
|
[f'[1][0], f'[1][1] ] ] [5(x-5), 5(x-5)] ]
|
||
|
|
||
|
And thus computes the commitments
|
||
|
|
||
|
COM([ f[j][i]], zA) = zA*G + (x-7)*H[0,0] + 7*H[0,1] + 5*H[1,0] + (x-5)*H[1,1]
|
||
|
COM([f'[j][i]], zC) = zC*G + 7(x-7)*H[0,0] + 7(x-7)*H[0,1] + 5*(x-5)*H[1,0]
|
||
|
+ 5(x-5)*H[1,1]
|
||
|
|
||
|
On the other hand, she is given B and A, and with her x, she can compute xB+A:
|
||
|
|
||
|
xB + A = x(rB*G + 1*H[0,0] + 0*H[0,1] + 0*H[1,0] + 1*H[1,1])
|
||
|
+ (rA*G - 7*H[0,0] + 7*H[0,1] + 5*H[1,0] - 5*H[1,1])
|
||
|
= (rB*x + rA)*G + (x-7)*H[0,0] + 7*H[0,1] + 5*H[1,0] + (x-5)*H[1,1]
|
||
|
|
||
|
Lo and behold, this matches COM([ f[j][i]], zA). She can do the same with C,D:
|
||
|
|
||
|
xC + D = x(rC*G + 7*H[0,0] + 7*H[0,1] + 5*H[1,0] + 5*H[1,1])
|
||
|
+ (rD*G - 49*H[0,0] - 49*H[0,1] - 25*H[1,0] - 25*H[1,1])
|
||
|
= (rC*x + rD)*G + 7(x-7)*H[0,0] + 7(x-7)*H[0,1] + 5(x-5)*H[1,0]
|
||
|
+ 5*(x-5)*H[1,1]
|
||
|
|
||
|
Voila!
|
||
|
|
||
|
|
||
|
|
||
|
IV. REFERENCES
|
||
|
|
||
|
[1] Ruffing, Thyagarajan, Ronge, Schröder. "Boosting Private Payments in
|
||
|
Monero: New Attacks, Exact Cryptographic Definitions, and Sublinear
|
||
|
Ring Signatures." In preparation.
|
||
|
[2] Bootle, Cerulli, Chaidos, Ghadafi, Groth, Petit. "Short accountable
|
||
|
ring signatures based on DDH." European Symposium on Research in
|
||
|
Computer Security. Springer, Cham, 2015.
|
||
|
[3] Bellare, Mihir, and Gregory Neven. "Multi-signatures in the plain
|
||
|
public-key model and a general forking lemma." Proceedings of the 13th
|
||
|
ACM conference on Computer and communications security. ACM, 2006.
|
||
|
|
||
|
|