kzg 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +1 -1
- data/Gemfile +3 -1
- data/README.md +23 -1
- data/lib/kzg/commitment.rb +29 -17
- data/lib/kzg/polynomial.rb +84 -8
- data/lib/kzg/setting.rb +36 -5
- data/lib/kzg/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1d030fcbbf815eafe9c538839946e6337c2e9c60f1bcce5de79172b453c96fe9
|
4
|
+
data.tar.gz: 68c3d99c0cb6fea2f16e3617df6d198cae2cb352f22cd66c982ba362731a778c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a3cae69f35050d6dba026231c2d783204359140a94e406676fb178ff58cc1bdbe1a1e2e73124ea29679a4d5c3b95c22b0c5b90d1d7a2ea4c394bf9317b4926a4
|
7
|
+
data.tar.gz: 1d21a4db43881ce872e41954b116cee5603ee80a8b8e3b7e7b7efc01c317d9addb5c9cc78b07a84898279be41d0b941166ee6840e90be95e92929298e89f32ec
|
data/.rubocop.yml
CHANGED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -61,7 +61,19 @@ The committer can compute proof that the value of the polynomial (f(x)) for any
|
|
61
61
|
proof = commitment.compute_proof(35)
|
62
62
|
```
|
63
63
|
|
64
|
-
This proof is point in the `BLS::PointG1`.
|
64
|
+
This proof is a point in the `BLS::PointG1`.
|
65
|
+
|
66
|
+
#### Multi proof
|
67
|
+
|
68
|
+
A multi-proof for disclosing multiple x values is created as follows:
|
69
|
+
|
70
|
+
```ruby
|
71
|
+
x = [1, 2, 3]
|
72
|
+
|
73
|
+
multi_proof = commitment.compute_multi_proof(x)
|
74
|
+
```
|
75
|
+
|
76
|
+
This proof is a point in the `BLS::PointG1`.
|
65
77
|
|
66
78
|
### Verify
|
67
79
|
|
@@ -73,6 +85,16 @@ y = 808951170278371
|
|
73
85
|
setting.valid_proof?(commitment.value, proof, x, y)
|
74
86
|
```
|
75
87
|
|
88
|
+
#### Multi proof
|
89
|
+
|
90
|
+
The validity of multiple proofs disclosing more than one value can be verified as follows:
|
91
|
+
|
92
|
+
```ruby
|
93
|
+
x = [1, 2, 3]
|
94
|
+
y = [55, 9217, 280483]
|
95
|
+
setting.valid_multi_proof?(commitment.value, multi_proof, x, y)
|
96
|
+
```
|
97
|
+
|
76
98
|
### Use as vector commitment
|
77
99
|
|
78
100
|
When used as a Vector commitment, the value to be committed is encoded in a polynomial expression as the evaluated value of the polynomial.
|
data/lib/kzg/commitment.rb
CHANGED
@@ -7,11 +7,19 @@ module KZG
|
|
7
7
|
|
8
8
|
# Create commitment
|
9
9
|
# @param [KZG::Setting] setting
|
10
|
-
# @param [
|
11
|
-
def initialize(setting, polynomial
|
10
|
+
# @param [KZG::Polynomial] polynomial
|
11
|
+
def initialize(setting, polynomial)
|
12
12
|
@setting = setting
|
13
13
|
@polynomial = polynomial
|
14
|
-
@value =
|
14
|
+
@value =
|
15
|
+
polynomial
|
16
|
+
.coeffs
|
17
|
+
.map
|
18
|
+
.with_index do |c, i|
|
19
|
+
c = c.is_a?(BLS::Fr) ? c : BLS::Fr.new(c)
|
20
|
+
c.value.zero? ? BLS::PointG1::ZERO : setting.g1_points[i] * c
|
21
|
+
end
|
22
|
+
.inject(&:+)
|
15
23
|
end
|
16
24
|
|
17
25
|
# Create commitment using coefficients.
|
@@ -22,26 +30,30 @@ module KZG
|
|
22
30
|
raise KZG::Error,
|
23
31
|
"coeffs length is greater than the number of secret parameters."
|
24
32
|
end
|
25
|
-
|
26
|
-
coeffs
|
27
|
-
.map
|
28
|
-
.with_index do |c, i|
|
29
|
-
c = c.is_a?(BLS::Fr) ? c : BLS::Fr.new(c)
|
30
|
-
c.value.zero? ? BLS::PointG1::ZERO : setting.g1_points[i] * c
|
31
|
-
end
|
32
|
-
.inject(&:+)
|
33
|
-
Commitment.new(setting, KZG::Polynomial.new(coeffs), value)
|
33
|
+
Commitment.new(setting, KZG::Polynomial.new(coeffs))
|
34
34
|
end
|
35
35
|
|
36
36
|
# Compute KZG proof for polynomial in coefficient form at position x.
|
37
37
|
# @param [Integer] x Position
|
38
38
|
# @return [BLS::PointG1] Proof.
|
39
39
|
def compute_proof(x)
|
40
|
-
divisor =
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
40
|
+
divisor = Polynomial.new([BLS::Fr.new(x).negate, BLS::Fr::ONE])
|
41
|
+
quotient_poly = polynomial / divisor
|
42
|
+
Commitment.new(setting, quotient_poly).value
|
43
|
+
end
|
44
|
+
|
45
|
+
# Compute KZG multi proof using list of x coordinate.
|
46
|
+
# @param [Array(Integer)] x An array of x coordinate.
|
47
|
+
# @return [BLS::PointG1]
|
48
|
+
def compute_multi_proof(x)
|
49
|
+
y = x.map { |i| polynomial.eval_at(i) }
|
50
|
+
# compute i(x)
|
51
|
+
i_poly = Polynomial.lagrange_interpolate(x, y)
|
52
|
+
# compute z(x)
|
53
|
+
z_poly = Polynomial.zero_poly(x)
|
54
|
+
# compute q(x) = (p(x) - i(x)) / z(x)
|
55
|
+
quotient_poly = (polynomial - i_poly) / z_poly
|
56
|
+
Commitment.new(setting, quotient_poly).value
|
45
57
|
end
|
46
58
|
end
|
47
59
|
end
|
data/lib/kzg/polynomial.rb
CHANGED
@@ -37,6 +37,15 @@ module KZG
|
|
37
37
|
Polynomial.new(coeffs)
|
38
38
|
end
|
39
39
|
|
40
|
+
# Create polynomial from array of x coordinate like f(x) = (x - x0)(x - x1)...(x - xn)
|
41
|
+
# @param [Array(Integer)] x An array of x coordinate.
|
42
|
+
# @return [KZG::Polynomial]
|
43
|
+
def self.zero_poly(x)
|
44
|
+
poleis =
|
45
|
+
x.map { |v| Polynomial.new([BLS::Fr.new(v).negate, BLS::Fr::ONE]) }
|
46
|
+
poleis[1..].inject(poleis.first) { |result, poly| result * poly }
|
47
|
+
end
|
48
|
+
|
40
49
|
# Evaluate polynomial for given +x+ using Horner's method.
|
41
50
|
# @param [Integer | BLS::Fr] x
|
42
51
|
# @return [BLS::Fr] Evaluated value.
|
@@ -52,21 +61,71 @@ module KZG
|
|
52
61
|
last
|
53
62
|
end
|
54
63
|
|
55
|
-
#
|
56
|
-
# @param [
|
57
|
-
# @return [
|
58
|
-
|
64
|
+
# Returns a new polynomial that is the sum of the given polynomial and this polynomial.
|
65
|
+
# @param [KZG::Polynomial] other
|
66
|
+
# @return [KZG::Polynomial] Sum of polynomial.
|
67
|
+
# @raise ArgumentError
|
68
|
+
def add(other)
|
69
|
+
unless other.is_a?(Polynomial)
|
70
|
+
raise ArgumentError, "add target must be Polynomial"
|
71
|
+
end
|
72
|
+
|
73
|
+
sum = process(coeffs, other.coeffs) { |a, b| a + b }
|
74
|
+
Polynomial.new(sum)
|
75
|
+
end
|
76
|
+
alias + add
|
77
|
+
|
78
|
+
# Returns a new polynomial subtracting the given polynomial from self.
|
79
|
+
# @param [KZG::Polynomial] other
|
80
|
+
# @return [KZG::Polynomial] Subtracted polynomial.
|
81
|
+
# @raise ArgumentError
|
82
|
+
def sub(other)
|
83
|
+
unless other.is_a?(Polynomial)
|
84
|
+
raise ArgumentError, "subtract target must be Polynomial"
|
85
|
+
end
|
86
|
+
|
87
|
+
Polynomial.new(process(coeffs, other.coeffs) { |a, b| a - b })
|
88
|
+
end
|
89
|
+
alias - sub
|
90
|
+
|
91
|
+
# Return a new polynomial that multiply self and the given polynomial.
|
92
|
+
# @param [KZG::Polynomial] other Other polynomial
|
93
|
+
# @return [KZG::Polynomial] Multiplied polynomial
|
94
|
+
# @return ArgumentError
|
95
|
+
def multiply(other)
|
96
|
+
unless other.is_a?(Polynomial)
|
97
|
+
raise ArgumentError, "multiply target must be Polynomial"
|
98
|
+
end
|
99
|
+
new_coeffs = Array.new(coeffs.length + other.coeffs.length - 1)
|
100
|
+
coeffs.each.with_index do |a, i|
|
101
|
+
other.coeffs.each.with_index do |b, j|
|
102
|
+
k = i + j
|
103
|
+
new_coeffs[k] = a * b + (new_coeffs[k] || BLS::Fr::ZERO)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
Polynomial.new(new_coeffs)
|
107
|
+
end
|
108
|
+
alias * multiply
|
109
|
+
|
110
|
+
# Return a new polynomial that divide self and the given polynomial, i.e. self / other.
|
111
|
+
# @param [KZG::Polynomial] other Other polynomial
|
112
|
+
# @return [KZG::Polynomial] Divided polynomial
|
113
|
+
# @return ArgumentError
|
114
|
+
def div(other)
|
115
|
+
unless other.is_a?(Polynomial)
|
116
|
+
raise ArgumentError, "divide target must be Polynomial"
|
117
|
+
end
|
59
118
|
a = coeffs.dup
|
60
119
|
a_pos = a.length - 1
|
61
|
-
b_pos =
|
120
|
+
b_pos = other.coeffs.length - 1
|
62
121
|
diff = a_pos - b_pos
|
63
122
|
quotient_poly = []
|
64
123
|
|
65
124
|
while diff >= 0
|
66
|
-
quot = a[a_pos] /
|
125
|
+
quot = a[a_pos] / other.coeffs[b_pos]
|
67
126
|
i = b_pos
|
68
127
|
while i >= 0
|
69
|
-
tmp = quot *
|
128
|
+
tmp = quot * other.coeffs[i]
|
70
129
|
tmp2 = a[diff + i] - tmp
|
71
130
|
a[diff + i] = tmp2
|
72
131
|
i -= 1
|
@@ -75,7 +134,24 @@ module KZG
|
|
75
134
|
a_pos -= 1
|
76
135
|
diff -= 1
|
77
136
|
end
|
78
|
-
quotient_poly
|
137
|
+
Polynomial.new(quotient_poly)
|
138
|
+
end
|
139
|
+
alias / div
|
140
|
+
|
141
|
+
def ==(other)
|
142
|
+
return false unless other.is_a?(Polynomial)
|
143
|
+
coeffs == other.coeffs
|
144
|
+
end
|
145
|
+
|
146
|
+
private
|
147
|
+
|
148
|
+
def process(a, b)
|
149
|
+
length = [a.length, b.length].max
|
150
|
+
length.times.map do |i|
|
151
|
+
c1 = i < a.length ? a[i] : BLS::Fr::ZERO
|
152
|
+
c2 = i < b.length ? b[i] : BLS::Fr::ZERO
|
153
|
+
yield(c1, c2)
|
154
|
+
end
|
79
155
|
end
|
80
156
|
end
|
81
157
|
end
|
data/lib/kzg/setting.rb
CHANGED
@@ -5,12 +5,10 @@ module KZG
|
|
5
5
|
class Setting
|
6
6
|
attr_reader :g1_points, :g2_points
|
7
7
|
|
8
|
-
# @param [Array
|
9
|
-
# @param [Array
|
8
|
+
# @param [Array(BLS::PointG1)] g1_points
|
9
|
+
# @param [Array(BLS::PointG2)] g2_points
|
10
10
|
def initialize(g1_points, g2_points)
|
11
|
-
|
12
|
-
raise KZG::Error, "g1_points and g2_points must be array."
|
13
|
-
end
|
11
|
+
raise KZG::Error, "g1_points must be array." unless g1_points.is_a?(Array)
|
14
12
|
unless g1_points.all? { |g| g.is_a?(BLS::PointG1) }
|
15
13
|
raise KZG::Error, "All elements of g1_points must be BLS::PointG1."
|
16
14
|
end
|
@@ -48,5 +46,38 @@ module KZG
|
|
48
46
|
exp = (lhs * rhs).final_exponentiate
|
49
47
|
exp == BLS::Fq12::ONE
|
50
48
|
end
|
49
|
+
|
50
|
+
# Check a proof for a KZG commitment for an evaluation f(x) = y
|
51
|
+
# @param [BLS::PointG1] commit_point
|
52
|
+
# @param [BLS::PointG1] proof
|
53
|
+
# @param [Array(Integer|BLS::Fr)] x
|
54
|
+
# @param [Array(Integer|BLS::Fr)] y
|
55
|
+
def valid_multi_proof?(commit_point, proof, x, y)
|
56
|
+
x = x.map { |v| v.is_a?(BLS::Fr) ? v.value : v }
|
57
|
+
y = y.map { |v| v.is_a?(BLS::Fr) ? v.value : v }
|
58
|
+
# compute i(x)
|
59
|
+
i_poly = Polynomial.lagrange_interpolate(x, y)
|
60
|
+
# compute z(x)
|
61
|
+
z_poly = Polynomial.zero_poly(x)
|
62
|
+
# e([commitment - interpolation_polynomial(s)]^(-1), [1]) * e([proof], [s^n - x^n]) = 1
|
63
|
+
is = Commitment.new(self, i_poly).value
|
64
|
+
lhs =
|
65
|
+
BLS.pairing(
|
66
|
+
(commit_point - is).negate,
|
67
|
+
BLS::PointG2::BASE,
|
68
|
+
with_final_exp: false
|
69
|
+
)
|
70
|
+
z_commit =
|
71
|
+
z_poly
|
72
|
+
.coeffs
|
73
|
+
.map
|
74
|
+
.with_index do |c, i|
|
75
|
+
c.value.zero? ? BLS::PointG2::ZERO : g2_points[i] * c
|
76
|
+
end
|
77
|
+
.inject(&:+)
|
78
|
+
rhs = BLS.pairing(proof, z_commit, with_final_exp: false)
|
79
|
+
exp = (lhs * rhs).final_exponentiate
|
80
|
+
exp == BLS::Fq12::ONE
|
81
|
+
end
|
51
82
|
end
|
52
83
|
end
|
data/lib/kzg/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kzg
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- azuchi
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-02-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bls12-381
|