Module: KZG

Defined in:
lib/kzg.rb,
lib/kzg/setting.rb,
lib/kzg/version.rb,
lib/kzg/commitment.rb,
lib/kzg/polynomial.rb

Overview

KZG Commitment library.

Defined Under Namespace

Classes: Commitment, Error, Polynomial, Setting

Constant Summary collapse

FIELD_ELEMENT_BYTE_SIZE =

Size of the canonical encoding of a field element, as used by EIP-4844 and its test vectors: 32 bytes, big endian.

32
FIELD_ELEMENT_HEX =
/\A(?:[0-9a-fA-F]{2}){#{FIELD_ELEMENT_BYTE_SIZE}}\z/.freeze
VERSION =
"0.4.0"

Class Method Summary collapse

Class Method Details

.decode_field_element(hex) ⇒ BLS::Fr

Decode a field element from its canonical representation.

BLS::Fr.new reduces whatever it is handed modulo the group order. That is the right answer for an element built in memory, where -6 and r - 6 are two ways of writing one element, and the wrong one for an element arriving as bytes: it leaves 1 and r + 1 as two spellings of a single claim, and a proof for either verifies against the other. Anything that deduplicates, indexes or compares by the encoding then sees two claims where there is one.

This is the scalar counterpart of BLS::PointG1.from_hex, which refuses a non-canonical point for the same reason. Together they cover both halves of the wire format; neither KZG::Setting#valid_proof? nor BLS::Fr can, since neither is handed the encoding.

or above the group order.

Parameters:

  • hex (String)

    a field element, 32 bytes big endian in hex, with no 0x prefix.

Returns:

  • (BLS::Fr)

    the decoded field element.

Raises:

  • (KZG::Error)

    Occur when hex is not 32 bytes of hex digits, or encodes a value at



40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/kzg.rb', line 40

def decode_field_element(hex)
  unless hex.is_a?(String) && hex.match?(FIELD_ELEMENT_HEX)
    raise KZG::Error,
          "Field element must be #{FIELD_ELEMENT_BYTE_SIZE} bytes in hex."
  end

  value = hex.to_i(16)
  unless value < BLS::Curve::R
    raise KZG::Error, "Field element must be less than the group order."
  end

  BLS::Fr.new(value)
end

.setup_params(secret, n) ⇒ KZG::Setting

Setup elements of elliptic curve from secret. Note: Since the random secret must not be known to anyone, this Trusted Setup usually needs to be performed using an MPC or similar. [s]_2 to check a proof against.

Parameters:

  • secret (Integer)

    random secret.

  • n (Integer)

    number of parameters. At least 2, since a setting needs [1]_2 and

Returns:

Raises:

  • (KZG::Error)

    Occur when n is below 2, or when the secret reduces to zero.



62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/kzg.rb', line 62

def setup_params(secret, n)
  raise KZG::Error, "n must be 2 or more." unless n.is_a?(Integer) && n >= 2

  s = BLS::Fr.new(secret)
  # A secret of zero, or any multiple of the group order, leaves every point above [s^0] at
  # infinity: a setup that commits to nothing but the constant term.
  if s.zero?
    raise KZG::Error, "secret must not be a multiple of the group order."
  end

  s1 = Array.new(n)
  s2 = Array.new(n)
  s_pow = BLS::Fr::ONE
  n.times do |i|
    s1[i] = BLS::PointG1::BASE * s_pow
    s2[i] = BLS::PointG2::BASE * s_pow
    tmp = s_pow
    s_pow = tmp * s
  end
  Setting.new(s1, s2)
end