Skip to main content

threshold

RSA threshold signature allows multiple parties to sign a piece of data with their own private keys without exposing their private keys. When verifying, only with a certain number of signatures need to be obtained (Based on the threshold setting, the number is usually less than the number of participants), the validity of the data can be verified. This increases the efficiency and security of multi-party participation.

Goar’ s threshold.go implements the threshold signature algorithm, which allows developers to quickly and conveniently generate key pairs, and key distribution, improving the security and reliability of applications.

Usage

Key Generation

k := 3
l := 5
bitSize := 1024
keyShares, keyMeta, err := goar.CreateTcKeyPair(bitSize, k, l)
if err != nil {
panic(err)
}
fmt.Printf("%v\n%v", keyShares, keyMeta)

Note:

  • l is the number of participants.
  • k is the threshold value, which is set to 3 in this example, which means that in this application case of threshold signature, the number of participants is 5. And the validity of the data can be verified only by obtaining the signatures of any 3 participants. .
  • bitSize is related to the binary length of the RSA private key when the key is generated. Goar limits this value to the range [512,4096], because it is too short and will lead to insufficient security while too long can increase security. But the efficiency of private key generation will be greatly reduced. In a production environment, setting this value to 4096 is safe enough.
  • keyMeta is the generated public key of threshold signature, which contains the number of participants l and the threshold value k . This public key will be distributed to all participants.
  • keyShares is the generated distribution key, which is an array of length l. Each element in the array will be distributed to all participants separately as their private key for signing.

Creating a TcSign instance

data := []byte("data need to sign")
salt := sha256.Sum256([]byte("everHash salt aaa"))
ts, err := goar.NewTcSign(keyMeta, data, salt[:])

Note:

  • data is the data that needs to be signed.
  • salt is the added random noise.
  • keyMeta is the public key when generating the threshold signature. The main functions of creating a TcSign instance are:
  • For the participants, after creating a TcSign instance through keyMeta, they can use the distribution key obtained by themselves to sign the data, and then submit the signature to the verifier for signature aggregation and verification.
  • For the verifier, after creating a TcSign case through keyMeta, they can verify whether the received signature of the participant is legal. If it is legal, the signature will be aggregated to verify the threshold signature. The following describes how the participants and the verifiers use the TcSign instance.

Participants carry out the threshold signature

ts, err := goar.NewTcSign(keyMeta, data, salt[:])
key := keyShares[0]
sig0, err := ts.ThresholdSign(key)

Note:

  • key is the distribution key obtained by participant number 0 and keyShares is the distribution key generated for all participants in the key generation step.
  • sig0 is the signature of participant No. 0 to the data.

Participants can submit the signature to the verifier (signature aggregator) after threshold signature of the data.

Verifying Signature

signedShares := tcrsa.SigShareList{
sig0,
sig1,
sig2,
}
// assemble
signature, err := ts.AssembleSigShares(signedShares)
if err != nil {
panic(err)
}
// verify
signHashed := sha256.Sum256(data)
err = rsa.VerifyPSS(keyMeta.PublicKey, crypto.SHA256, signHashed[:], signature, nil)

Note:

  • signedShares contains the signatures of participants 0, 1, 2 to the data.
  • signature is the signature generated by the verifier after aggregating the signatures of participants 0, 1, and 2.

After the aggregated signature is obtained, the validity of the data signature can be verified. In this example, we provide the signatures of three participants, which satisfy the threshold value k.