Class: FROST::Context

Inherits:
Object
  • Object
show all
Defined in:
lib/frost/context.rb

Constant Summary collapse

CTX_STRING_SECP256K1 =
"FROST-secp256k1-SHA256-v1"
CTX_STRING_SECP256K1_TR =
"FROST-secp256k1-SHA256-TR-v1"
CTX_STRING_P256 =
"FROST-P256-SHA256-v1"

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(group, type) ⇒ Context

Constructor

Parameters:

  • group (ECDSA::Group)

    The elliptic curve group.

  • type (Symbol)

    FROST::Type

Raises:

  • (ArgumentError)


15
16
17
18
19
20
# File 'lib/frost/context.rb', line 15

def initialize(group, type)
  raise ArgumentError, "group must be ECDSA::Group." unless group.is_a?(ECDSA::Group)
  FROST::Type.validate!(type)
  @group = group
  @type = type
end

Instance Attribute Details

#groupObject (readonly)

Returns the value of attribute group.



8
9
10
# File 'lib/frost/context.rb', line 8

def group
  @group
end

#typeObject (readonly)

Returns the value of attribute type.



9
10
11
# File 'lib/frost/context.rb', line 9

def type
  @type
end

Instance Method Details

#convert_commitment_share(group_commitment, commitment_share) ⇒ ECDSA::Point

Convert commitment share depending on context.

Parameters:

  • group_commitment (ECDSA::Point)
  • commitment_share (ECDSA::Point)

Returns:

  • (ECDSA::Point)

    Converted commitment share.



68
69
70
71
# File 'lib/frost/context.rb', line 68

def convert_commitment_share(group_commitment, commitment_share)
  return commitment_share unless taproot?
  group_commitment.y.even? ? commitment_share : commitment_share.negate
end

#convert_signer_nocnes(group_commitment, nonces) ⇒ Array

Negate nonces depending on context.

Parameters:

  • group_commitment (ECDSA::Point)
  • nonces (Array)

    Pair of nonce values (hiding_nonce, binding_nonce) for signer_i.

Returns:

  • (Array)

    Converted nonces.



59
60
61
62
# File 'lib/frost/context.rb', line 59

def convert_signer_nocnes(group_commitment, nonces)
  return nonces unless taproot?
  group_commitment.y.even? ? nonces : nonces.map(&:to_negate)
end

#ctx_stringString

Get context string.

Returns:

  • (String)

    context string.

Raises:

  • (ArgumentError)


31
32
33
34
35
36
37
38
39
40
41
# File 'lib/frost/context.rb', line 31

def ctx_string
  case group
  when ECDSA::Group::Secp256k1
    type == FROST::Type::RFC9591 ? CTX_STRING_SECP256K1 : CTX_STRING_SECP256K1_TR
  when ECDSA::Group::Secp256r1
    CTX_STRING_P256
  else
    # TODO support other suite.
    raise RuntimeError, "group #{group} dose not supported."
  end
end

#normalize(point) ⇒ String

Normalize elliptic curve point. If type is BIP-340, return as x-only public key.

Parameters:

  • point (ECDSA::Point)

Returns:

  • (String)

    Normalized point string with binary format.



47
48
49
50
51
52
53
# File 'lib/frost/context.rb', line 47

def normalize(point)
  if taproot?
    ECDSA::Format::FieldElementOctetString.encode(point.x, group.field)
  else
    [point.to_hex].pack("H*")
  end
end

#pre_verify(public_key, signature) ⇒ Array

Preprocess verify inputs, negating the VerifyingKey and ‘signature.R` if required by BIP-340.

Parameters:

Returns:

  • (Array)

    An array of public_key and signature.



77
78
79
80
81
82
83
84
85
# File 'lib/frost/context.rb', line 77

def pre_verify(public_key, signature)
  if taproot?
    public_key = public_key.y.even? ? public_key : public_key.negate
    r = signature.r.y.even? ? signature.r : signature.r.negate
    [public_key, FROST::Signature.new(self, r, signature.s)]
  else
    [public_key, signature]
  end
end

#taproot?Boolean

Check this context is taproot or not?

Returns:

  • (Boolean)


24
25
26
# File 'lib/frost/context.rb', line 24

def taproot?
  type == FROST::Type::TAPROOT
end