mirror of https://github.com/zcash/zips.git
update to last RFC version
This commit is contained in:
parent
b2e5634248
commit
5183e06b2f
127
zip-frost.rst
127
zip-frost.rst
|
@ -170,13 +170,14 @@ as follows: ::
|
||||||
Inputs:
|
Inputs:
|
||||||
- commitment_list = [(i, hiding_nonce_commitment_i, binding_nonce_commitment_i), ...],
|
- commitment_list = [(i, hiding_nonce_commitment_i, binding_nonce_commitment_i), ...],
|
||||||
a list of commitments issued by each participant, where each element in the list
|
a list of commitments issued by each participant, where each element in the list
|
||||||
indicates the participant identifier i and their two commitment Element values
|
indicates a NonZeroScalar identifier i and two commitment Element values
|
||||||
(hiding_nonce_commitment_i, binding_nonce_commitment_i). This list MUST be sorted
|
(hiding_nonce_commitment_i, binding_nonce_commitment_i). This list MUST be sorted
|
||||||
in ascending order by participant identifier.
|
in ascending order by identifier.
|
||||||
- msg, the message to be signed.
|
- msg, the message to be signed.
|
||||||
- randomizer_point, an element in G.
|
- randomizer_point, an element in G.
|
||||||
|
|
||||||
Outputs: A list of (identifier, Scalar) tuples representing the binding factors.
|
Outputs:
|
||||||
|
- binding_factor_list, a list of (NonZeroScalar, Scalar) tuples representing the binding factors.
|
||||||
|
|
||||||
def compute_binding_factors(commitment_list, msg, randomizer_point):
|
def compute_binding_factors(commitment_list, msg, randomizer_point):
|
||||||
msg_hash = H4(msg)
|
msg_hash = H4(msg)
|
||||||
|
@ -216,22 +217,23 @@ The `sign` function is changed to receive `randomizer_point` and incorporate it
|
||||||
into the computation of the binding factor. It is specified as the following: ::
|
into the computation of the binding factor. It is specified as the following: ::
|
||||||
|
|
||||||
Inputs:
|
Inputs:
|
||||||
- identifier, Identifier i of the participant. Note identifier will never equal 0.
|
- identifier, identifier i of the participant, a NonZeroScalar.
|
||||||
- sk_i, Signer secret key share, a Scalar.
|
- sk_i, Signer secret key share, a Scalar.
|
||||||
- group_public_key, public key corresponding to the group signing key,
|
- group_public_key, public key corresponding to the group signing key,
|
||||||
an Element in G.
|
an Element.
|
||||||
- nonce_i, pair of Scalar values (hiding_nonce, binding_nonce) generated in
|
- nonce_i, pair of Scalar values (hiding_nonce, binding_nonce) generated in
|
||||||
round one.
|
round one.
|
||||||
- msg, the message to be signed (sent by the Coordinator).
|
- msg, the message to be signed, a byte string.
|
||||||
- commitment_list =
|
- commitment_list =
|
||||||
[(j, hiding_nonce_commitment_j, binding_nonce_commitment_j), ...], a
|
[(j, hiding_nonce_commitment_j, binding_nonce_commitment_j), ...], a
|
||||||
list of commitments issued in Round 1 by each participant and sent by the Coordinator.
|
list of commitments issued in Round 1 by each participant and sent by the Coordinator.
|
||||||
Each element in the list indicates the participant identifier j and their two commitment
|
Each element in the list indicates a NonZeroScalar identifier j and two commitment
|
||||||
Element values (hiding_nonce_commitment_j, binding_nonce_commitment_j).
|
Element values (hiding_nonce_commitment_j, binding_nonce_commitment_j).
|
||||||
This list MUST be sorted in ascending order by participant identifier.
|
This list MUST be sorted in ascending order by identifier.
|
||||||
- randomizer_point, an element in G (sent by the Coordinator).
|
- randomizer_point, an element in G (sent by the Coordinator).
|
||||||
|
|
||||||
Outputs: a Scalar value representing the signature share
|
Outputs:
|
||||||
|
- sig_share, a signature share, a Scalar.
|
||||||
|
|
||||||
def sign(identifier, sk_i, group_public_key, nonce_i, msg, commitment_list):
|
def sign(identifier, sk_i, group_public_key, nonce_i, msg, commitment_list):
|
||||||
# Compute the randomized group public key
|
# Compute the randomized group public key
|
||||||
|
@ -244,9 +246,9 @@ into the computation of the binding factor. It is specified as the following: ::
|
||||||
# Compute the group commitment
|
# Compute the group commitment
|
||||||
group_commitment = compute_group_commitment(commitment_list, binding_factor_list)
|
group_commitment = compute_group_commitment(commitment_list, binding_factor_list)
|
||||||
|
|
||||||
# Compute Lagrange coefficient
|
# Compute the interpolating value
|
||||||
participant_list = participants_from_commitment_list(commitment_list)
|
participant_list = participants_from_commitment_list(commitment_list)
|
||||||
lambda_i = derive_lagrange_coefficient(identifier, participant_list)
|
lambda_i = derive_interpolating_value(identifier, participant_list)
|
||||||
|
|
||||||
# Compute the per-message challenge
|
# Compute the per-message challenge
|
||||||
challenge = compute_challenge(group_commitment, randomized_group_public_key, msg)
|
challenge = compute_challenge(group_commitment, randomized_group_public_key, msg)
|
||||||
|
@ -261,29 +263,67 @@ into the computation of the binding factor. It is specified as the following: ::
|
||||||
Signature Share Verification and Aggregation
|
Signature Share Verification and Aggregation
|
||||||
''''''''''''''''''''''''''''''''''''''''''''
|
''''''''''''''''''''''''''''''''''''''''''''
|
||||||
|
|
||||||
|
The `aggregate` function is changed to incorporate the randomizer as follows: ::
|
||||||
|
|
||||||
|
Inputs:
|
||||||
|
- commitment_list =
|
||||||
|
[(j, hiding_nonce_commitment_j, binding_nonce_commitment_j), ...], a
|
||||||
|
list of commitments issued in Round 1 by each participant, where each element
|
||||||
|
in the list indicates a NonZeroScalar identifier j and two commitment
|
||||||
|
Element values (hiding_nonce_commitment_j, binding_nonce_commitment_j).
|
||||||
|
This list MUST be sorted in ascending order by identifier.
|
||||||
|
- msg, the message to be signed, a byte string.
|
||||||
|
- sig_shares, a set of signature shares z_i, Scalar values, for each participant,
|
||||||
|
of length NUM_PARTICIPANTS, where MIN_PARTICIPANTS <= NUM_PARTICIPANTS <= MAX_PARTICIPANTS.
|
||||||
|
- group_public_key, public key corresponding to the group signing key,
|
||||||
|
- randomizer, the randomizer Scalar.
|
||||||
|
|
||||||
|
Outputs:
|
||||||
|
- (R, z), a Schnorr signature consisting of an Element R and Scalar z.
|
||||||
|
- randomized_group_public_key, the randomized group public key
|
||||||
|
|
||||||
|
def aggregate(commitment_list, msg, sig_shares, group_public_key, randomizer):
|
||||||
|
# Compute the binding factors
|
||||||
|
binding_factor_list = compute_binding_factors(commitment_list, msg)
|
||||||
|
|
||||||
|
# Compute the group commitment
|
||||||
|
group_commitment = compute_group_commitment(commitment_list, binding_factor_list)
|
||||||
|
|
||||||
|
# Compute the challenge
|
||||||
|
randomized_group_public_key = group_public_key + G * randomizer
|
||||||
|
challenge = compute_challenge(group_commitment, randomized_group_public_key, msg)
|
||||||
|
|
||||||
|
# Compute aggregated signature
|
||||||
|
z = Scalar(0)
|
||||||
|
for z_i in sig_shares:
|
||||||
|
z = z + z_i
|
||||||
|
return (group_commitment, z + randomizer * challenge), randomized_group_public_key
|
||||||
|
|
||||||
|
|
||||||
The `verify_signature_share` is changed to incorporate the randomizer point,
|
The `verify_signature_share` is changed to incorporate the randomizer point,
|
||||||
as follows: ::
|
as follows: ::
|
||||||
|
|
||||||
Inputs:
|
Inputs:
|
||||||
- identifier, Identifier i of the participant. Note: identifier MUST never equal 0.
|
- identifier, identifier i of the participant, a NonZeroScalar.
|
||||||
- PK_i, the public key for the ith participant, where PK_i = G.ScalarBaseMult(sk_i),
|
- PK_i, the public key for the i-th participant, where PK_i = G.ScalarBaseMult(sk_i),
|
||||||
an Element in G
|
an Element.
|
||||||
- comm_i, pair of Element values in G (hiding_nonce_commitment, binding_nonce_commitment)
|
- comm_i, pair of Element values in G (hiding_nonce_commitment, binding_nonce_commitment)
|
||||||
generated in round one from the ith participant.
|
generated in round one from the i-th participant.
|
||||||
- sig_share_i, a Scalar value indicating the signature share as produced in
|
- sig_share_i, a Scalar value indicating the signature share as produced in
|
||||||
round two from the ith participant.
|
round two from the i-th participant.
|
||||||
- commitment_list =
|
- commitment_list =
|
||||||
[(j, hiding_nonce_commitment_j, binding_nonce_commitment_j), ...], a
|
[(j, hiding_nonce_commitment_j, binding_nonce_commitment_j), ...], a
|
||||||
list of commitments issued in Round 1 by each participant, where each element
|
list of commitments issued in Round 1 by each participant, where each element
|
||||||
in the list indicates the participant identifier j and their two commitment
|
in the list indicates a NonZeroScalar identifier j and two commitment
|
||||||
Element values (hiding_nonce_commitment_j, binding_nonce_commitment_j).
|
Element values (hiding_nonce_commitment_j, binding_nonce_commitment_j).
|
||||||
This list MUST be sorted in ascending order by participant identifier.
|
This list MUST be sorted in ascending order by identifier.
|
||||||
- group_public_key, public key corresponding to the group signing key,
|
- group_public_key, public key corresponding to the group signing key,
|
||||||
an Element in G.
|
an Element.
|
||||||
- msg, the message to be signed.
|
- msg, the message to be signed, a byte string.
|
||||||
- randomizer_point, an element in G.
|
- randomizer_point, an element in G.
|
||||||
|
|
||||||
Outputs: True if the signature share is valid, and False otherwise.
|
Outputs:
|
||||||
|
- True if the signature share is valid, and False otherwise.
|
||||||
|
|
||||||
def verify_signature_share(identifier, PK_i, comm_i, sig_share_i, commitment_list,
|
def verify_signature_share(identifier, PK_i, comm_i, sig_share_i, commitment_list,
|
||||||
group_public_key, msg, randomizer_point):
|
group_public_key, msg, randomizer_point):
|
||||||
|
@ -304,9 +344,9 @@ as follows: ::
|
||||||
# Compute the challenge
|
# Compute the challenge
|
||||||
challenge = compute_challenge(group_commitment, randomized_group_public_key, msg)
|
challenge = compute_challenge(group_commitment, randomized_group_public_key, msg)
|
||||||
|
|
||||||
# Compute Lagrange coefficient
|
# Compute the interpolating value
|
||||||
participant_list = participants_from_commitment_list(commitment_list)
|
participant_list = participants_from_commitment_list(commitment_list)
|
||||||
lambda_i = derive_lagrange_coefficient(identifier, participant_list)
|
lambda_i = derive_interpolating_value(identifier, participant_list)
|
||||||
|
|
||||||
# Compute relation values
|
# Compute relation values
|
||||||
l = G.ScalarBaseMult(sig_share_i)
|
l = G.ScalarBaseMult(sig_share_i)
|
||||||
|
@ -314,27 +354,6 @@ as follows: ::
|
||||||
|
|
||||||
return l == r
|
return l == r
|
||||||
|
|
||||||
The `aggregate` function is changed to incorporate the randomizer as follows: ::
|
|
||||||
|
|
||||||
Inputs:
|
|
||||||
- group_commitment, the group commitment returned by compute_group_commitment,
|
|
||||||
an Element in G.
|
|
||||||
- sig_shares, a set of signature shares z_i, Scalar values, for each participant,
|
|
||||||
of length NUM_PARTICIPANTS, where MIN_PARTICIPANTS <= NUM_PARTICIPANTS <= MAX_PARTICIPANTS.
|
|
||||||
- group_public_key, public key corresponding to the group signing key,
|
|
||||||
- challenge, the challenge returned by compute_challenge, a Scalar.
|
|
||||||
- randomizer, the randomizer Scalar.
|
|
||||||
|
|
||||||
Outputs:
|
|
||||||
- (R, z), a Schnorr signature consisting of an Element R and Scalar z.
|
|
||||||
- randomized_group_public_key, the randomized group public key
|
|
||||||
|
|
||||||
def aggregate(group_commitment, sig_shares, group_public_key, challenge, randomizer):
|
|
||||||
randomized_group_public_key = group_public_key + G * randomizer
|
|
||||||
z = 0
|
|
||||||
for z_i in sig_shares:
|
|
||||||
z = z + z_i
|
|
||||||
return (group_commitment, z + randomizer * challenge), randomized_group_public_key
|
|
||||||
|
|
||||||
|
|
||||||
Ciphersuites
|
Ciphersuites
|
||||||
|
@ -351,17 +370,17 @@ Authorization Signatures as specified in [#protocol-concretespendauthsig]_.
|
||||||
|
|
||||||
- Order: 6554484396890773809930967563523245729705921265872317281365359162392183254199 (see [#protocol-jubjub]_)
|
- Order: 6554484396890773809930967563523245729705921265872317281365359162392183254199 (see [#protocol-jubjub]_)
|
||||||
- Identity: as defined in [#protocol-jubjub]_
|
- Identity: as defined in [#protocol-jubjub]_
|
||||||
- RandomScalar(): Implemented by returning a uniformly random Scalar in the range \[0, `G.Order()` - 1\].
|
- RandomScalar(): Implemented by returning a uniformly random Scalar in the range
|
||||||
Refer to {{frost-randomscalar}} for implementation guidance.
|
\[0, `G.Order()` - 1\]. Refer to {{frost-randomscalar}} for implementation guidance.
|
||||||
- SerializeElement(P): Implemented as :math:`\mathsf{repr}_\mathbb{J}(P)` as defined in [#protocol-jubjub]_
|
- SerializeElement(P): Implemented as :math:`\mathsf{repr}_\mathbb{J}(P)` as defined in [#protocol-jubjub]_
|
||||||
- DeserializeElement(P): Implemented as :math:`\mathsf{abst}_\mathbb{J}(P)` as defined in [#protocol-jubjub]_,
|
- DeserializeElement(P): Implemented as :math:`\mathsf{abst}_\mathbb{J}(P)` as defined in [#protocol-jubjub]_,
|
||||||
failing if :math:`\bot` is returned. Additionally, this function validates that the resulting
|
failing if :math:`\bot` is returned. Additionally, this function validates that the resulting
|
||||||
element is not the group identity element.
|
element is not the group identity element, returning an error if the check fails.
|
||||||
- SerializeScalar: Implemented by outputting the little-endian 32-byte encoding
|
- SerializeScalar: Implemented by outputting the little-endian 32-byte encoding
|
||||||
of the Scalar value.
|
of the Scalar value.
|
||||||
- DeserializeScalar: Implemented by attempting to deserialize a Scalar from a
|
- DeserializeScalar: Implemented by attempting to deserialize a Scalar from a
|
||||||
little-endian 32-byte string. This function can fail if the input does not represent a Scalar
|
little-endian 32-byte string. This function can fail if the input does not
|
||||||
in the range \[0, `G.Order()` - 1\].
|
represent a Scalar in the range \[0, `G.Order()` - 1\].
|
||||||
|
|
||||||
- Hash (`H`): BLAKE2b-512 [#BLAKE]_ (BLAKE2b with 512-bit output and 16-byte personalization string),
|
- Hash (`H`): BLAKE2b-512 [#BLAKE]_ (BLAKE2b with 512-bit output and 16-byte personalization string),
|
||||||
and Nh = 64.
|
and Nh = 64.
|
||||||
|
@ -392,17 +411,17 @@ Authorization Signatures as specified in [#protocol-concretespendauthsig]_.
|
||||||
|
|
||||||
- Order: 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 (see [#protocol-pallasandvesta]_)
|
- Order: 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 (see [#protocol-pallasandvesta]_)
|
||||||
- Identity: as defined in [#protocol-pallasandvesta]_
|
- Identity: as defined in [#protocol-pallasandvesta]_
|
||||||
- RandomScalar(): Implemented by returning a uniformly random Scalar in the range \[0, `G.Order()` - 1\].
|
- RandomScalar(): Implemented by returning a uniformly random Scalar in the range
|
||||||
Refer to {{frost-randomscalar}} for implementation guidance.
|
\[0, `G.Order()` - 1\]. Refer to {{frost-randomscalar}} for implementation guidance.
|
||||||
- SerializeElement(P): Implemented as :math:`\mathsf{repr}_\mathbb{P}(P)` as defined in [#protocol-pallasandvesta]_
|
- SerializeElement(P): Implemented as :math:`\mathsf{repr}_\mathbb{P}(P)` as defined in [#protocol-pallasandvesta]_
|
||||||
- DeserializeElement(P): Implemented as :math:`\mathsf{abst}_\mathbb{P}(P)` as defined in [#protocol-pallasandvesta]_,
|
- DeserializeElement(P): Implemented as :math:`\mathsf{abst}_\mathbb{P}(P)` as defined in [#protocol-pallasandvesta]_,
|
||||||
failing if :math:`\bot` is returned. Additionally, this function validates that the resulting
|
failing if :math:`\bot` is returned. Additionally, this function validates that the resulting
|
||||||
element is not the group identity element.
|
element is not the group identity element, returning an error if the check fails.
|
||||||
- SerializeScalar: Implemented by outputting the little-endian 32-byte encoding
|
- SerializeScalar: Implemented by outputting the little-endian 32-byte encoding
|
||||||
of the Scalar value.
|
of the Scalar value.
|
||||||
- DeserializeScalar: Implemented by attempting to deserialize a Scalar from a
|
- DeserializeScalar: Implemented by attempting to deserialize a Scalar from a
|
||||||
little-endian 32-byte string. This function can fail if the input does not represent a Scalar
|
little-endian 32-byte string. This function can fail if the input does not
|
||||||
in the range \[0, `G.Order()` - 1\].
|
represent a Scalar in the range \[0, `G.Order()` - 1\].
|
||||||
|
|
||||||
- Hash (`H`): BLAKE2b-512 [#BLAKE]_ (BLAKE2b with 512-bit output and 16-byte personalization string),
|
- Hash (`H`): BLAKE2b-512 [#BLAKE]_ (BLAKE2b with 512-bit output and 16-byte personalization string),
|
||||||
and Nh = 64.
|
and Nh = 64.
|
||||||
|
|
Loading…
Reference in New Issue