Class: KZG::Setting
- Inherits:
-
Object
- Object
- KZG::Setting
- Defined in:
- lib/kzg/setting.rb
Instance Attribute Summary collapse
-
#g1_points ⇒ Object
readonly
Returns the value of attribute g1_points.
-
#g2_points ⇒ Object
readonly
Returns the value of attribute g2_points.
Instance Method Summary collapse
- #==(other) ⇒ Object
-
#initialize(g1_points, g2_points) ⇒ Setting
constructor
checked against.
-
#valid_multi_proof?(commit_point, proof, x, y) ⇒ Boolean
Check a proof for a KZG commitment for an evaluation f(x) = y is a claim that does not verify, so a malformed x/y is false rather than an exception.
-
#valid_proof?(commit_point, proof, x, y) ⇒ Boolean
Check a proof for a KZG commitment for an evaluation f(x) = y.
Constructor Details
#initialize(g1_points, g2_points) ⇒ Setting
checked against. its group, or when g2_points is too short to verify with.
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
# File 'lib/kzg/setting.rb', line 13 def initialize(g1_points, g2_points) raise KZG::Error, "g1_points must be array." unless g1_points.is_a?(Array) raise KZG::Error, "g2_points must be array." unless g2_points.is_a?(Array) unless g1_points.all? { |g| g.is_a?(BLS::PointG1) } raise KZG::Error, "All elements of g1_points must be BLS::PointG1." end unless g2_points.all? { |g| g.is_a?(BLS::PointG2) } raise KZG::Error, "All elements of g2_points must be BLS::PointG2." end # valid_proof? reads g2_points[1], so a setting short of it can verify nothing. Refused # here rather than at verification time, where it is a nil that has travelled some way # from the setup that omitted it. if g2_points.length < 2 raise KZG::Error, "g2_points must have at least 2 elements." end @g1_points = g1_points @g2_points = g2_points end |
Instance Attribute Details
#g1_points ⇒ Object (readonly)
Returns the value of attribute g1_points.
6 7 8 |
# File 'lib/kzg/setting.rb', line 6 def g1_points @g1_points end |
#g2_points ⇒ Object (readonly)
Returns the value of attribute g2_points.
6 7 8 |
# File 'lib/kzg/setting.rb', line 6 def g2_points @g2_points end |
Instance Method Details
#==(other) ⇒ Object
33 34 35 36 37 |
# File 'lib/kzg/setting.rb', line 33 def ==(other) return false unless other.is_a?(Setting) g1_points == other.g1_points && g2_points == other.g2_points end |
#valid_multi_proof?(commit_point, proof, x, y) ⇒ Boolean
Check a proof for a KZG commitment for an evaluation f(x) = y is a claim that does not verify, so a malformed x/y is false rather than an exception.
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
# File 'lib/kzg/setting.rb', line 71 def valid_multi_proof?(commit_point, proof, x, y) return false unless g1_element?(commit_point) && g1_element?(proof) # Nothing is claimed over an empty set of points, and a y that does not pair up with an # x leaves the interpolation below indexing past the end of it. return false if x.empty? || x.length != y.length # Both commitments below take one setup point per coefficient, and z(x) is of degree # x.length, so it needs one G2 point more than there are x. A claim larger than that is # one this setting cannot weigh, rather than one it has weighed and rejected, but it # reaches here from whoever is being verified and so cannot raise either. if x.length > g1_points.length || x.length >= g2_points.length return false end x = x.map { |v| v.is_a?(BLS::Fr) ? v.value : v } y = y.map { |v| v.is_a?(BLS::Fr) ? v.value : v } # Interpolation through a repeated x is undefined, and lagrange_interpolate raises on # it. The x here comes from whoever the proof is being verified for, so a repeat has to # be reported as a failed proof instead of letting the exception escape. Compared after # reduction, since x and x + BLS::Curve::R are the same field element. return false if x.map { |v| BLS::Fr.new(v).value }.uniq.length < x.length # compute i(x) i_poly = Polynomial.lagrange_interpolate(x, y) # compute z(x) z_poly = Polynomial.zero_poly(x) # e([commitment - interpolation_polynomial(s)]^(-1), [1]) * e([proof], [s^n - x^n]) = 1 is = Commitment.new(self, i_poly).value lhs = BLS.partial_pairing((commit_point - is).negate, BLS::PointG2::BASE) z_commit = z_poly .coeffs .map .with_index do |c, i| c.value.zero? ? BLS::PointG2::ZERO : g2_points[i] * c end .inject(BLS::PointG2::ZERO, &:+) rhs = BLS.partial_pairing(proof, z_commit) exp = (lhs * rhs).final_exponentiate exp == BLS::Fp12::ONE end |
#valid_proof?(commit_point, proof, x, y) ⇒ Boolean
Check a proof for a KZG commitment for an evaluation f(x) = y
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
# File 'lib/kzg/setting.rb', line 45 def valid_proof?(commit_point, proof, x, y) return false unless g1_element?(commit_point) && g1_element?(proof) x = x.is_a?(BLS::Fr) ? x : BLS::Fr.new(x) y = y.is_a?(BLS::Fr) ? y : BLS::Fr.new(y) xg2 = x.value.zero? ? BLS::PointG2::ZERO : BLS::PointG2::BASE * x yg = y.value.zero? ? BLS::PointG1::ZERO : BLS::PointG1::BASE * y # e([commitment - y]^(-1), [1]) * e([proof], [s - x]) = 1 # partial_pairing rather than pairing: a proof at infinity, or a commitment that # cancels with [y], is a degenerate input a verifier can be handed and has to come out # as false rather than as a BLS::PairingError. e(O, Q) = e(P, O) = 1 leaves the # equation above intact. lhs = BLS.partial_pairing((commit_point - yg).negate, BLS::PointG2::BASE) rhs = BLS.partial_pairing(proof, g2_points[1] - xg2) exp = (lhs * rhs).final_exponentiate exp == BLS::Fp12::ONE end |