Skip to content

Instantly share code, notes, and snippets.

@phyro
Last active June 29, 2021 19:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save phyro/c8213747fcf288ff64ed97f4dc1f2192 to your computer and use it in GitHub Desktop.
Save phyro/c8213747fcf288ff64ed97f4dc1f2192 to your computer and use it in GitHub Desktop.
Am I OK? #1

Am I OK riddle1

Figure out if the cryptography below is safe.

Split signature

Below is a new signature scheme. The intuition is that given a public key P, we can break it into two parts P1, P2 such that p1*G + p2*G = P. If P has a form 0*H + x*G then both P1 and P2 should have a form 0*H + y*G (unless the prover picked v*H + p1*G and -v*H + p2*G, but they won't be able to sign this), so we can multiply any of the two points by a random factor and we should still be able to produce a signature for e1*P1 + e2*P2. This equation form also allows for a simple noninteractive aggregation of s values which means that for 100 signatures, we only need 100*32 + 32 bytes - the last 32 bytes being for the summed up s.

Scheme

Suppose Alice wants to prove she knows the private key of curve point P. She picks a random scalar p1 to get another curve point p1*G = P1 and then we define P2 = P - P1. This means that P1 + P2 = P. Only Alice knows the private key of P2. We verify that neither P1 or P2 are 0*G.

Let e1 = H(P1 | P2 | M) be a challenge for P1 and e2 = H(P2 | P1 | M) be a challenge for P2. We interpret S = e1*P1 + e2*P2 as our new public key and show the private key s such that s*G = S. The signature from public key P on message M is a pair (P1, s). As shown above, we can compute P2 from P and P1. Since s is a combination of two random private keys, it should give no information about the private key of P.

If we were dealing with Pedersen commitments, we can only show such s if P itself had a form 0*H + x*G. Why is that? Because if it had v*H + x*G, then at least one of P1 and P2 would need to have a non-zero H part because v*H + x*G = P1 + P2. Due to random scaling of P1 and P2 from e1 and e2, the prover would not be able to show s such that s*G = S. On top of that, neither P1 or P2 can have a form v*H + x*G because they both receive random scaling from the challenges e1, e2.

Batch verification

e1*P1 + e2*P2 = s1*G
e3*P3 + e3*P4 = s2*G
...
e100*P100 + e101*P101 = s100*G

which gives us a grand formula

e1*P1 + e2*P2 + e3*P3 + e3*P4 + ... + e100*P100 + e101*P101 = (s1+s2+...+s100)*G 

Unlike in Schnorr, it is safe to naively noninteractively sum up the s values. Why?

Given an invalid signature equation EQ1, it is impossible to produce EQ2 that would subtract the unknowns from EQ1 (due to random scaling) and produce a combined valid summed signature equation. The reason why this is impossible is because there does not exist an element in the equation that is not randomly scaled. Both P1 and P2 receive their own random scalings from the challenges e1, e2 - unlike in Schnorr where R is defined completely by the user and can hence be set such that it subtracts public keys from a different signature equation. In other words, the verification equation for a Schnorr signature is only half-random because only the P part of the equation is randomized while R stays user defined. Split signatures add randomness to every element in the equation and hence has all parts of the verification equation randomized which prevents any two equations to "help" each other.

Why it is not safe to naively sum up the s values in Schnorr is described in "Batch verification" section on https://phyro.github.io/grinvestigation/schnorr.html.

Interactive sig aggregation

Similarly like with Schnorr signatures, two parties can interact to produce a single signature on the same message M.

e1 = H(P1a+P1b | P2a+P2b | M)

e2 = H(P2a+P2b | P1a+P1b | M)

and the signature is (P1a + P1b, s1a + s1b).

Questions

Q: Could we use a single e for both P1 and P2?

A: No, this would leak the private key of P because if P = P1 + P2, then if we show s such that s*G = e*P1 + e*P2, we also show the private key of P because s*G = e*P1 + e*P2 = e*P from which we can derive that p = s/e.

Q: Could we have a simpler challenge?

A: Yes, we could define e1 = H(P1 | P2 | M) and then e2 = H(e1) to avoid having two challenges with the actual data in the hash. The same simplification of challenge e2 also makes the interactive signature aggregation a bit simpler.

Q: Could we introduce random scaling to R in Schnorr and also get simpler half aggregation?

A: Again, we could define e2 = H(e) and then the modified Schnorr verification equation would be e*P + e2*R = s*G. Proving the knowledge of a private key would still work and this variant would be safer from some of the attacks that try to inject public keys for which they don't know the private key e.g. signatures helping each other. Both modified Schnorr and Split sigs come with an additional hash computation and scalar multiplication per signature verification.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment