object FrostUtil
- Alphabetic
- By Inheritance
- FrostUtil
- AnyRef
- Any
- Hide All
- Show All
- Public
- Protected
Value Members
- final def !=(arg0: Any): Boolean
- Definition Classes
- AnyRef → Any
- final def ##: Int
- Definition Classes
- AnyRef → Any
- final def ==(arg0: Any): Boolean
- Definition Classes
- AnyRef → Any
- val COORDINATOR_ID: Long
Fixed participant ID used to represent the coordinator in deterministic signing.
Fixed participant ID used to represent the coordinator in deterministic signing.
In FROST deterministic signing, the coordinator aggregates nonces from other participants but doesn't contribute a secret share. This fixed ID (1337) is used to identify the coordinator's nonce contribution when aggregating nonces.
- def aggregateNonces(pubnonces: Vector[FrostNoncePub], participantIdentifiers: Vector[Long]): FrostNoncePub
Aggregates public nonces from multiple participants.
Aggregates public nonces from multiple participants.
This function combines the public nonces from all signing participants into a single aggregated nonce. Each participant contributes two nonce points (R1_i, R2_i), and this function computes the aggregated nonces as:
- R1 = sum(R1_i) for all participants i
- R2 = sum(R2_i) for all participants i
The aggregated nonce is used in the session context to compute the binding factor
band the effective nonce point R = R1 + b·R2.- pubnonces
vector of public nonces from each participant
- participantIdentifiers
vector of participant IDs corresponding to each nonce (must be same length as pubnonces)
- returns
the aggregated public nonce containing (R1, R2)
- Exceptions thrown
IllegalArgumentExceptionif lengths don't match or any nonce point is at infinity
- final def asInstanceOf[T0]: T0
- Definition Classes
- Any
- def clone(): AnyRef
- Attributes
- protected[lang]
- Definition Classes
- AnyRef
- Annotations
- @throws(classOf[java.lang.CloneNotSupportedException]) @native()
- def computeThresholdPubKey(pubshares: Vector[ECPublicKey], ids: Vector[Long]): ECPublicKey
Computes the threshold public key from participant public shares.
Computes the threshold public key from participant public shares.
This function derives the aggregate (threshold) public key from the individual public shares of the participants. The threshold public key is computed using Lagrange interpolation:
Q = sum(λ_i · X_i) for all participants i
where:
- λ_i is the Lagrange interpolation coefficient for participant i
- X_i is participant i's public share (X_i = share_i · G)
This public key represents the aggregate key that can be used to verify FROST signatures. Any t-of-n participants can collaborate to sign with this public key.
- pubshares
vector of public shares from each participant
- ids
vector of participant identifiers (same order as pubshares)
- returns
the threshold public key
- Exceptions thrown
IllegalArgumentExceptionif the computed key is the point at infinity
- def deriveCoefficient(seed: ByteVector, idx: Int): FieldElement
Derives a single polynomial coefficient from a seed and index.
Derives a single polynomial coefficient from a seed and index.
This function generates one coefficient by hashing the seed concatenated with the coefficient index. Each coefficient is derived independently using the FROST coefficient generation hash.
- seed
the seed bytes for coefficient derivation
- idx
the coefficient index (0 for constant term, 1 for linear term, etc.)
- returns
the coefficient as a FieldElement
- def deriveCoefficients(polygen: ByteVector, threshold: Int): Vector[FieldElement]
Derives all polynomial coefficients from a seed.
Derives all polynomial coefficients from a seed.
This function generates t polynomial coefficients (a_0, a_1, ..., a_{t-1}) by hashing the seed with different indices. These coefficients define the secret sharing polynomial.
- polygen
the seed bytes for coefficient derivation
- threshold
the threshold (number of coefficients to generate)
- returns
vector of t field element coefficients
- def deriveInterpolatingValue(ids: Vector[Long], myId: Long): FieldElement
Computes the FROST Lagrange coefficient \(\lambda_{myId}\) for combining secret shares.
Computes the FROST Lagrange coefficient \(\lambda_{myId}\) for combining secret shares.
The coefficient computed is: lambda_myId = product_{j != myId} (id_j + 1) \/ (id_j - myId)
All arithmetic is performed in the prime field represented by
FieldElement.Preconditions:
idscontainsmyId.idscontains no duplicates.- all identifiers in
idsandmyIdare non\-negative.
Throws an IllegalArgumentException if any precondition fails or if the denominator evaluates to zero (so the multiplicative inverse does not exist in the field).
- ids
Vector of participant identifiers (distinct, non\-negative).
- myId
Identifier for which to compute the Lagrange coefficient.
- returns
The Lagrange coefficient as a
FieldElement.
- def deterministicSign(secshare: FieldElement, signerId: Long, aggOtherNonce: FrostNoncePub, signersContext: FrostSigningContext, tweaks: Vector[FieldElement], isXOnly: Vector[Boolean], message: ByteVector, auxRandOpt: Option[ByteVector]): (FrostNoncePub, FieldElement)
Generates a deterministic partial signature for stateless signing.
Generates a deterministic partial signature for stateless signing.
This function enables a signer to generate both their nonce and partial signature deterministically from their secret share and the coordinator's aggregated nonce. This is useful for stateless signing where the signer doesn't need to store generated nonces between rounds.
The deterministic nonces are derived by hashing:
- The secret share (optionally mixed with auxiliary randomness)
- The aggregated nonce from other participants
- The tweaked threshold public key
- The message
This ensures the nonces are deterministic but unique per message and signing session.
- secshare
the signer's secret share
- signerId
the identifier of this signer
- aggOtherNonce
the aggregated public nonce from other participants (typically the coordinator)
- signersContext
the signing context with participant information
- tweaks
optional tweaks to apply to the threshold public key
- isXOnly
flags indicating which tweaks are x-only
- message
the message to be signed
- auxRandOpt
optional auxiliary randomness to mix with the secret share (recommended for additional security)
- returns
a tuple of (public nonce, partial signature)
- Exceptions thrown
IllegalArgumentExceptionif derived nonces are zero, points at infinity, or signature verification fails
- final def eq(arg0: AnyRef): Boolean
- Definition Classes
- AnyRef
- def equals(arg0: AnyRef): Boolean
- Definition Classes
- AnyRef → Any
- def finalize(): Unit
- Attributes
- protected[lang]
- Definition Classes
- AnyRef
- Annotations
- @throws(classOf[java.lang.Throwable])
- def generateShare(seed: ByteVector, threshold: Int, id: Long): FieldElement
Generates a single secret share using polynomial evaluation.
Generates a single secret share using polynomial evaluation.
This function evaluates the secret sharing polynomial at a specific participant ID to generate their secret share. The polynomial is of degree t-1, where t is the threshold.
The share is computed as: share_i = a_0 + a_1·i + a_2·i2 + ... + a_{t-1}·i{t-1}
where a_0, a_1, ..., a_{t-1} are the polynomial coefficients derived from the seed.
- seed
the seed bytes used to derive polynomial coefficients
- threshold
the threshold (determines polynomial degree = threshold - 1)
- id
the participant identifier (must be positive)
- returns
the secret share for this participant as a FieldElement
- def generateShares(seed: ECPrivateKey, threshold: Int, numShares: Int): FrostShareGenResult
Generates FROST secret shares using a trusted dealer.
Generates FROST secret shares using a trusted dealer.
This function implements the trusted dealer key generation for FROST. The dealer generates:
- Secret shares for n participants using polynomial secret sharing
- VSS (Verifiable Secret Sharing) commitments that allow participants to verify their shares
- A threshold public key representing the aggregate signing key
The polynomial has degree t-1, which means any t participants can collaborate to produce a signature, but fewer than t cannot.
Each participant receives their secret share and can verify it against the public commitments using
vssVerify.Security note: This is a trusted dealer setup where the dealer knows all secret shares. For production use, consider using a distributed key generation (DKG) protocol instead.
- seed
the secret seed used to generate the polynomial (must be kept secret by dealer)
- threshold
the minimum number of signers required (t, must be > 1)
- numShares
the total number of shares to generate (n, must be >= threshold)
- returns
FrostShareGenResult containing participant IDs, secret shares, and VSS commitments
- Exceptions thrown
IllegalArgumentExceptionif threshold <= 1 or numShares < threshold- See also
- final def getClass(): Class[_ <: AnyRef]
- Definition Classes
- AnyRef → Any
- Annotations
- @native()
- def hashCode(): Int
- Definition Classes
- AnyRef → Any
- Annotations
- @native()
- def hashFrostAux(bytes: ByteVector): ByteVector
- def hashFrostCoeffGen(bytes: ByteVector): ByteVector
- def hashFrostDeterministicNonce(secshare: FieldElement, aggOtherNonce: FrostNoncePub, tweakThresholdPubKey: XOnlyPubKey, message: ByteVector, i: Byte): ByteVector
- def hashFrostDeterministicNonce(bytes: ByteVector): ByteVector
- def hashFrostNonce(bytes: ByteVector): ByteVector
- def hashFrostNonceCoef(bytes: ByteVector): ByteVector
- final def isInstanceOf[T0]: Boolean
- Definition Classes
- Any
- final def ne(arg0: AnyRef): Boolean
- Definition Classes
- AnyRef
- def nonceGen(rand: ByteVector, secshare: Option[FieldElement], pubshare: Option[ECPublicKey], threshold_pk: Option[XOnlyPubKey], message: Option[ByteVector], extra_in: Option[ByteVector]): (FrostNoncePriv, FrostNoncePub)
Generates a FROST nonce pair (secret and public).
Generates a FROST nonce pair (secret and public).
This function generates two secret nonces (k1, k2) and their corresponding public nonces (R1, R2) for use in a FROST signing session. The nonces are derived deterministically from the provided inputs using tagged hashes.
The nonces can be optionally bound to:
- The signer's secret share (for additional security)
- The signer's public share
- The threshold public key (to bind to a specific signing group)
- A specific message (to prevent nonce reuse across messages)
- Extra input data
Security note: The
randparameter must be 32 bytes of cryptographically secure random data. Ifsecshareis provided, the randomness is mixed with the secret share using the auxiliary hash to protect against side-channel attacks.- rand
32 bytes of random data (must be cryptographically secure)
- secshare
optional secret share to mix with randomness (recommended for security)
- pubshare
optional public share to bind nonces to a specific participant
- threshold_pk
optional threshold public key to bind nonces to a signing group
- message
optional message to bind nonces to (prevents reuse across messages)
- extra_in
optional extra input data for domain separation
- returns
a tuple of (secret nonce, public nonce)
- Exceptions thrown
IllegalArgumentExceptionif derived nonce preimages are zero or points at infinity
- final def notify(): Unit
- Definition Classes
- AnyRef
- Annotations
- @native()
- final def notifyAll(): Unit
- Definition Classes
- AnyRef
- Annotations
- @native()
- def partialSigAgg(partialSigs: Vector[FieldElement], ids: Vector[Long], sessionContext: FrostSessionContext): SchnorrDigitalSignature
Aggregates partial signatures into a final Schnorr signature.
Aggregates partial signatures into a final Schnorr signature.
This function combines the partial signatures from all signing participants into a complete Schnorr signature. The aggregation computes:
s = sum(s_i) + e·g·tacc
where:
- s_i are the partial signatures
- e is the challenge scalar
- g is the parity multiplier for the aggregate public key
- tacc is the tweak accumulator
The final signature is (R, s) where R is the x-only nonce point from the session context.
- partialSigs
vector of partial signatures from each participant
- ids
vector of participant identifiers (same order as partialSigs)
- sessionContext
the session context containing session values (R, e, tweaks, etc.)
- returns
a complete BIP-340 Schnorr signature
- Exceptions thrown
IllegalArgumentExceptionif the number of partial signatures doesn't match the number of IDs
- def partialSigVerify(partialSig: FieldElement, pubnonces: Vector[FrostNoncePub], signersContext: FrostSigningContext, tweaks: Vector[FieldElement], isXonlyT: Vector[Boolean], message: ByteVector, signerId: Long): Boolean
Verifies a FROST partial signature.
Verifies a FROST partial signature.
This function verifies that a partial signature from a specific signer is valid. It reconstructs the session context from the provided inputs, aggregates the nonces, and then calls the internal verification function.
The verification checks that: s·G = R_i + e·λ·gacc·g·X_i
where:
- s is the partial signature
- R_i is the signer's contribution to the nonce (R1_i + b·R2_i)
- e is the challenge scalar
- λ is the Lagrange coefficient for this signer
- X_i is the signer's public share
- partialSig
the partial signature to verify
- pubnonces
vector of all participants' public nonces
- signersContext
the signing context with participant information
- tweaks
optional tweaks applied to the threshold public key
- isXonlyT
flags indicating which tweaks are x-only
- message
the message that was signed
- signerId
the identifier of the signer whose signature is being verified
- returns
true if the partial signature is valid, false otherwise
- Exceptions thrown
IllegalArgumentExceptionif signerId is not in the signing context
- def partialSigVerifyInternal(partialSig: FieldElement, signerId: Long, pubNonce: FrostNoncePub, pubshare: ECPublicKey, sessionCtx: FrostSessionContext): Boolean
Internal partial signature verification (used by sign and partialSigVerify).
Internal partial signature verification (used by sign and partialSigVerify).
This function performs the actual verification of a partial signature using the session context that has already been constructed. It checks the signing equation:
s·G = R_i + e·λ·gacc·g·X_i
where:
- s is the partial signature scalar
- G is the generator point
- R_i = R1_i + b·R2_i (possibly negated based on aggregate R's parity)
- e is the challenge scalar
- λ is the Lagrange coefficient
- gacc and g are parity accumulators
- X_i is the signer's public share
- partialSig
the partial signature scalar to verify
- signerId
the identifier of the signer
- pubNonce
the signer's public nonce (R1_i, R2_i)
- pubshare
the signer's public share (X_i)
- sessionCtx
the session context with all session values
- returns
true if the partial signature is valid, false otherwise
- Exceptions thrown
IllegalArgumentExceptionif signerId or pubshare are not in the session context
- def sign(secNonce: FrostNoncePriv, secShare: FieldElement, signerId: Long, sessionContext: FrostSessionContext): FieldElement
Generates a FROST partial signature.
Generates a FROST partial signature.
This function produces a partial signature for a single participant in a FROST signing session. The partial signature is computed as:
s = k1 + b·k2 + e·λ·d
where:
- k1, k2 are the signer's secret nonces (possibly negated based on R's parity)
- b is the nonce binding factor
- e is the challenge scalar
- λ (lambda) is the Lagrange interpolation coefficient for this signer
- d is the adjusted secret share (gacc·g·secShare)
The function internally verifies the computed partial signature before returning it.
- secNonce
the signer's secret nonce pair (k1, k2)
- secShare
the signer's secret share (must be non-zero)
- signerId
the identifier of this signer (must be in the session context)
- sessionContext
the signing session context containing aggregated nonces, tweaks, and message
- returns
the partial signature as a FieldElement
- Exceptions thrown
IllegalArgumentExceptionif signerId is invalid, secShare is zero, derived pubshare doesn't match context, or signature verification fails
- final def synchronized[T0](arg0: => T0): T0
- Definition Classes
- AnyRef
- def toString(): String
- Definition Classes
- AnyRef → Any
- def vssCommitment(polygen: ByteVector, threshold: Int): Vector[ECPublicKey]
Generates VSS (Verifiable Secret Sharing) commitments.
Generates VSS (Verifiable Secret Sharing) commitments.
This function computes the public commitments for each polynomial coefficient. Each commitment is C_j = a_j·G, where a_j is the j-th coefficient and G is the generator point.
These commitments allow participants to verify their secret shares without revealing the shares themselves.
- polygen
the seed bytes used to derive polynomial coefficients
- threshold
the threshold (determines number of commitments = threshold)
- returns
vector of public key commitments (one per polynomial coefficient)
- def vssVerify(share: FieldElement, id: Long, commitments: Vector[ECPublicKey]): Boolean
Verifies a secret share against VSS commitments.
Verifies a secret share against VSS commitments.
This function allows a participant to verify that their secret share is consistent with the public VSS commitments. It checks the equation:
share·G = sum(C_j · id^j) for j = 0 to t-1
where:
- share is the secret share
- G is the generator point
- C_j are the VSS commitments
- id is the participant identifier
- t is the threshold
This ensures the dealer generated the share correctly without revealing the share itself.
- share
the secret share to verify
- id
the participant identifier (must be positive)
- commitments
the VSS commitments from the dealer
- returns
true if the share is valid, false otherwise
- Exceptions thrown
IllegalArgumentExceptionif id is not positive
- final def wait(): Unit
- Definition Classes
- AnyRef
- Annotations
- @throws(classOf[java.lang.InterruptedException])
- final def wait(arg0: Long, arg1: Int): Unit
- Definition Classes
- AnyRef
- Annotations
- @throws(classOf[java.lang.InterruptedException])
- final def wait(arg0: Long): Unit
- Definition Classes
- AnyRef
- Annotations
- @throws(classOf[java.lang.InterruptedException]) @native()