gk15.go 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. /*
  2. * An implementation of Groth and Kohlweiss, "One-out-of-Many Proofs: Or
  3. * How to Leak a Secret and Spend a Coin", Eurocrypt 2015
  4. * https://eprint.iacr.org/2014/764.pdf
  5. */
  6. package main
  7. import (
  8. "fmt"
  9. "go.dedis.ch/kyber"
  10. "go.dedis.ch/kyber/util/random"
  11. )
  12. type GroupParams struct {
  13. /* A group of prime order */
  14. group kyber.Group
  15. /* Three generators of the group; the relative discrete logs
  16. * must be unknown. Commitments to a value x with randomness r
  17. * are x*A + r*B. Y is used to pad the list of commitments to a
  18. * power of 2. */
  19. A, B, Y kyber.Point
  20. }
  21. type PubState struct {
  22. cl, ca, cb, cd []kyber.Point
  23. }
  24. type PrivState struct {
  25. r, a, s, t, rho []kyber.Scalar
  26. }
  27. type Proof struct {
  28. }
  29. // Multiply a polynomial expressed as a slice of coefficients by the
  30. // scalar a
  31. func polymul(group kyber.Group, poly []kyber.Scalar, a kyber.Scalar) {
  32. numcoeffs := len(poly)
  33. for i := 0 ; i < numcoeffs ; i++ {
  34. poly[i] = group.Scalar().Mul(poly[i], a)
  35. }
  36. }
  37. // Multiply a polynomial expressed as a slice of coefficients by
  38. // the linear polynomial x+a
  39. func polymul_xplus(group kyber.Group, poly []kyber.Scalar, a kyber.Scalar) {
  40. numcoeffs := len(poly)
  41. if !poly[numcoeffs-1].Equal(group.Scalar().Zero()) {
  42. panic("Degree too large in multiplication")
  43. }
  44. for i := numcoeffs-1 ; i > 0 ; i-- {
  45. poly[i] = group.Scalar().Add(
  46. group.Scalar().Mul(poly[i], a), poly[i-1])
  47. }
  48. poly[0] = group.Scalar().Mul(poly[0], a)
  49. }
  50. /* Sigma protocol for one out of N commitments containing 0
  51. * Section 3 of https://eprint.iacr.org/2014/764.pdf
  52. */
  53. func ProofStep1(params GroupParams, c []kyber.Point, ell uint32, privkey kyber.Scalar) (PubState, PrivState) {
  54. N := uint32(len(c))
  55. rand := random.New()
  56. group := params.group
  57. // Find n := ceil(log_2(N))
  58. n := uint32(1)
  59. two_n := uint32(2) // 2^n
  60. for ; two_n < N ; {
  61. n += 1
  62. two_n *= 2
  63. }
  64. fmt.Printf("n = %d\n", n);
  65. // We will keep the notation of the paper:
  66. // r, a, s, t, cl, ca, cb are 1-based,
  67. // c, rho, cd are 0-based. The 1-based ones, we
  68. // just allocate an extra array element, and never
  69. // use element 0.
  70. var pub PubState
  71. var priv PrivState
  72. priv.r = make([]kyber.Scalar, n+1)
  73. priv.a = make([]kyber.Scalar, n+1)
  74. priv.s = make([]kyber.Scalar, n+1)
  75. priv.t = make([]kyber.Scalar, n+1)
  76. priv.rho = make([]kyber.Scalar, n)
  77. pub.cl = make([]kyber.Point, n+1)
  78. pub.ca = make([]kyber.Point, n+1)
  79. pub.cb = make([]kyber.Point, n+1)
  80. pub.cd = make([]kyber.Point, n)
  81. var j, k, mask uint32
  82. // mask = 2^k
  83. j = 1
  84. k = 0
  85. mask = 1
  86. for ; k < n ; {
  87. priv.r[j] = group.Scalar().Pick(rand)
  88. priv.a[j] = group.Scalar().Pick(rand)
  89. priv.s[j] = group.Scalar().Pick(rand)
  90. priv.t[j] = group.Scalar().Pick(rand)
  91. priv.rho[k] = group.Scalar().Pick(rand)
  92. pub.cl[j] = group.Point().Mul(priv.r[j], params.B)
  93. if (ell & mask) != 0 {
  94. pub.cl[j] = group.Point().Add(pub.cl[j], params.A)
  95. }
  96. pub.ca[j] = group.Point().Add(
  97. group.Point().Mul(priv.a[j], params.A),
  98. group.Point().Mul(priv.s[j], params.B))
  99. pub.cb[j] = group.Point().Mul(priv.t[j], params.B)
  100. if (ell & mask) != 0 {
  101. pub.cb[j] = group.Point().Add(pub.cb[j],
  102. group.Point().Mul(priv.a[j], params.A))
  103. }
  104. j++
  105. k++
  106. mask *= 2
  107. }
  108. k = 0
  109. for ; k < n ; {
  110. pub.cd[k] = group.Point().Mul(priv.rho[k], params.B)
  111. for i := uint32(0); i < two_n; i++ {
  112. // Compute the coefficients of p_i
  113. p_i := make([]kyber.Scalar, n+1)
  114. p_i[0] = group.Scalar().One()
  115. for t := uint32(1); t <= n; t++ {
  116. p_i[t] = group.Scalar().Zero()
  117. }
  118. // TODO: finish computation of p_i
  119. j = 1
  120. // jmask = 2^(j-1)
  121. jmask := uint32(1)
  122. for ; j <= n ; {
  123. if (i & jmask) != 0 {
  124. if (ell & jmask) != 0 {
  125. // Multiply p_i by x + a[j]
  126. polymul_xplus(group, p_i, priv.a[j])
  127. } else {
  128. // Multiply p_i by a[j]
  129. polymul(group, p_i, priv.a[j])
  130. }
  131. } else {
  132. negaj := group.Scalar().Neg(priv.a[j])
  133. if (ell & jmask) != 0 {
  134. // Multiply p_i by -a[j]
  135. polymul(group, p_i, negaj)
  136. } else {
  137. // Multiply p_i by x - a[j]
  138. polymul_xplus(group, p_i, negaj)
  139. }
  140. }
  141. j++
  142. jmask *= 2
  143. }
  144. if i == ell && !p_i[n].Equal(group.Scalar().One()) {
  145. panic("Leading coeff should be 1 but was not")
  146. }
  147. if i != ell && !p_i[n].Equal(group.Scalar().Zero()) {
  148. panic("Leading coeff should be 0 but was not")
  149. }
  150. if i < N {
  151. pub.cd[k] = group.Point().Add(pub.cd[k],
  152. group.Point().Mul(p_i[k], c[i]))
  153. } else {
  154. pub.cd[k] = group.Point().Add(pub.cd[k],
  155. group.Point().Mul(p_i[k], params.Y))
  156. }
  157. }
  158. k++
  159. mask *= 2
  160. }
  161. return pub, priv
  162. }
  163. func GenChallenge(params GroupParams, pub PubState) kyber.Scalar {
  164. return params.group.Scalar()
  165. }
  166. func ProofStep2(params GroupParams, priv PrivState, x kyber.Scalar) Proof {
  167. return Proof{}
  168. }
  169. func Verify(params GroupParams, pub PubState, x kyber.Scalar, proof Proof) bool {
  170. return false
  171. }