Documentation
¶
Overview ¶
Package bls implements BLS (Boneh-Lynn-Shacham) digital signatures as specified in draft-irtf-cfrg-bls-signature-06.
BLS signatures are built on pairing-friendly elliptic curves and support signature aggregation, where multiple signatures can be combined into a single compact signature while maintaining cryptographic security. This implementation supports the BLS12-381 curve family.
The package provides three signature schemes for rogue key attack prevention:
- Basic: requires all messages in an aggregate to be distinct
- Message Augmentation: prepends the public key to each message before signing
- Proof of Possession (POP): requires signers to prove knowledge of their secret key
Reference: https://www.ietf.org/archive/id/draft-irtf-cfrg-bls-signature-06.html
Index ¶
- Constants
- Variables
- func AggregateAll[PK curves.PairingFriendlyPoint[PK, PKFE, SG, SGFE, ET, S], ...](xs Xs) (X, error)
- func AugmentMessage[PK curves.Point[PK, PKFE, S], PKFE algebra.FieldElement[PKFE], ...](message []byte, publicKey PK) ([]byte, error)
- func RogueKeyPreventionAlgorithmIsSupported(alg RogueKeyPreventionAlgorithm) bool
- type CipherSuite
- type KeyGenerator
- func (kg *KeyGenerator[PK, FE, Sig, SigFE, E, S]) Generate(prng io.Reader) (*PrivateKey[PK, FE, Sig, SigFE, E, S], *PublicKey[PK, FE, Sig, SigFE, E, S], ...)
- func (kg *KeyGenerator[PK, FE, Sig, SigFE, E, S]) GenerateWithSeed(ikm []byte) (*PrivateKey[PK, FE, Sig, SigFE, E, S], *PublicKey[PK, FE, Sig, SigFE, E, S], ...)
- type KeyGeneratorOption
- type Message
- type PrivateKey
- func NewPrivateKey[PK curves.PairingFriendlyPoint[PK, PKFE, Sig, SigFE, E, S], ...](subGroup curves.PairingFriendlyCurve[PK, PKFE, Sig, SigFE, E, S], v S) (*PrivateKey[PK, PKFE, Sig, SigFE, E, S], error)
- func NewPrivateKeyFromBytes[PK curves.PairingFriendlyPoint[PK, PKFE, Sig, SigFE, E, S], ...](subGroup curves.PairingFriendlyCurve[PK, PKFE, Sig, SigFE, E, S], input []byte) (*PrivateKey[PK, PKFE, Sig, SigFE, E, S], error)
- func (sk *PrivateKey[PK, PKFE, Sig, SigFE, E, S]) Bytes() []byte
- func (sk *PrivateKey[PK, PKFE, Sig, SigFE, E, S]) Clone() *PrivateKey[PK, PKFE, Sig, SigFE, E, S]
- func (sk *PrivateKey[PK, PKFE, Sig, SigFE, E, S]) Equal(other *PrivateKey[PK, PKFE, Sig, SigFE, E, S]) bool
- func (sk *PrivateKey[PK, PKFE, Sig, SigFE, E, S]) Group() curves.Curve[PK, PKFE, S]
- func (*PrivateKey[PK, PKFE, Sig, SigFE, E, S]) Name() signatures.Name
- func (sk *PrivateKey[PK, PKFE, Sig, SigFE, E, S]) PublicKey() *PublicKey[PK, PKFE, Sig, SigFE, E, S]
- type ProofOfPossession
- func NewProofOfPossession[Sig curves.PairingFriendlyPoint[Sig, SigFE, PK, PKFE, E, S], ...](v Sig) (*ProofOfPossession[Sig, SigFE, PK, PKFE, E, S], error)
- func NewProofOfPossessionFromBytes[Sig curves.PairingFriendlyPoint[Sig, SigFE, PK, PKFE, E, S], ...](subGroup curves.PairingFriendlyCurve[Sig, SigFE, PK, PKFE, E, S], input []byte) (*ProofOfPossession[Sig, SigFE, PK, PKFE, E, S], error)
- func (pop *ProofOfPossession[Sig, SigFE, PK, PKFE, E, S]) Bytes() []byte
- func (pop *ProofOfPossession[Sig, SigFE, PK, PKFE, E, S]) Clone() *ProofOfPossession[Sig, SigFE, PK, PKFE, E, S]
- func (pop *ProofOfPossession[Sig, SigFE, PK, PKFE, E, S]) Equal(other *ProofOfPossession[Sig, SigFE, PK, PKFE, E, S]) bool
- func (pop *ProofOfPossession[Sig, SigFE, PK, PKFE, E, S]) HashCode() base.HashCode
- func (pop *ProofOfPossession[Sig, SigFE, PK, PKFE, E, S]) TryAdd(other *ProofOfPossession[Sig, SigFE, PK, PKFE, E, S]) (*ProofOfPossession[Sig, SigFE, PK, PKFE, E, S], error)
- func (pop *ProofOfPossession[Sig, SigFE, PK, PKFE, E, S]) Value() Sig
- type PublicKey
- func NewPublicKey[PK curves.PairingFriendlyPoint[PK, PKFE, Sig, SigFE, E, S], ...](v PK) (*PublicKey[PK, PKFE, Sig, SigFE, E, S], error)
- func NewPublicKeyFromBytes[PK curves.PairingFriendlyPoint[PK, PKFE, Sig, SigFE, E, S], ...](subGroup curves.PairingFriendlyCurve[PK, PKFE, Sig, SigFE, E, S], input []byte) (*PublicKey[PK, PKFE, Sig, SigFE, E, S], error)
- func (pk *PublicKey[P1, F1, P2, F2, E, S]) Bytes() []byte
- func (pk *PublicKey[P1, F1, P2, F2, E, S]) Clone() *PublicKey[P1, F1, P2, F2, E, S]
- func (pk *PublicKey[P1, F1, P2, F2, E, S]) Equal(other *PublicKey[P1, F1, P2, F2, E, S]) bool
- func (pk *PublicKey[P1, F1, P2, F2, E, S]) Group() curves.PairingFriendlyCurve[P1, F1, P2, F2, E, S]
- func (pk *PublicKey[P1, F1, P2, F2, E, S]) HashCode() base.HashCode
- func (pk *PublicKey[P1, F1, P2, F2, E, S]) IsShort() bool
- func (*PublicKey[P1, F1, P2, F2, E, S]) Name() signatures.Name
- func (pk *PublicKey[P1, F1, P2, F2, E, S]) TryAdd(other *PublicKey[P1, F1, P2, F2, E, S]) (*PublicKey[P1, F1, P2, F2, E, S], error)
- type RogueKeyPreventionAlgorithm
- type Scheme
- func NewLongKeyScheme[P1 curves.PairingFriendlyPoint[P1, FE1, P2, FE2, E, S], ...](curveFamily curves.PairingFriendlyFamily[P1, FE1, P2, FE2, E, S], ...) (*Scheme[P2, FE2, P1, FE1, E, S], error)
- func NewShortKeyScheme[P1 curves.PairingFriendlyPoint[P1, FE1, P2, FE2, E, S], ...](curveFamily curves.PairingFriendlyFamily[P1, FE1, P2, FE2, E, S], ...) (*Scheme[P1, FE1, P2, FE2, E, S], error)
- func (*Scheme[PK, PKFE, SG, SGFE, E, S]) AggregateSignatures(sigs ...*Signature[SG, SGFE, PK, PKFE, E, S]) (*Signature[SG, SGFE, PK, PKFE, E, S], error)
- func (s *Scheme[PK, PKFE, SG, SGFE, E, S]) CipherSuite() *CipherSuite
- func (s *Scheme[PK, PKFE, SG, SGFE, E, S]) KeySubGroup() curves.PairingFriendlyCurve[PK, PKFE, SG, SGFE, E, S]
- func (s *Scheme[PK, PKFE, SG, SGFE, E, S]) Keygen(opts ...KeyGeneratorOption[PK, PKFE, SG, SGFE, E, S]) (*KeyGenerator[PK, PKFE, SG, SGFE, E, S], error)
- func (*Scheme[PK, PKFE, SG, SGFE, E, S]) Name() signatures.Name
- func (s *Scheme[PK, PKFE, SG, SGFE, E, S]) RogueKeyPreventionAlgorithm() RogueKeyPreventionAlgorithm
- func (s *Scheme[PK, PKFE, SG, SGFE, E, S]) SignatureSubGroup() curves.PairingFriendlyCurve[SG, SGFE, PK, PKFE, E, S]
- func (s *Scheme[PK, PKFE, SG, SGFE, E, S]) Signer(privateKey *PrivateKey[PK, PKFE, SG, SGFE, E, S], ...) (*Signer[PK, PKFE, SG, SGFE, E, S], error)
- func (s *Scheme[PK, PKFE, SG, SGFE, E, S]) Variant() Variant
- func (s *Scheme[PK, PKFE, SG, SGFE, E, S]) Verifier(opts ...VerifierOption[PK, PKFE, SG, SGFE, E, S]) (*Verifier[PK, PKFE, SG, SGFE, E, S], error)
- type Signature
- func NewSignature[Sig curves.PairingFriendlyPoint[Sig, SigFE, PK, PKFE, E, S], ...](v Sig, pop *ProofOfPossession[Sig, SigFE, PK, PKFE, E, S]) (*Signature[Sig, SigFE, PK, PKFE, E, S], error)
- func NewSignatureFromBytes[Sig curves.PairingFriendlyPoint[Sig, SigFE, PK, PKFE, E, S], ...](subGroup curves.PairingFriendlyCurve[Sig, SigFE, PK, PKFE, E, S], input []byte, ...) (*Signature[Sig, SigFE, PK, PKFE, E, S], error)
- func (sig *Signature[Sig, SigFE, PK, PKFE, E, S]) Bytes() []byte
- func (sig *Signature[Sig, SigFE, PK, PKFE, E, S]) Clone() *Signature[Sig, SigFE, PK, PKFE, E, S]
- func (sig *Signature[Sig, SigFE, PK, PKFE, E, S]) Equal(other *Signature[Sig, SigFE, PK, PKFE, E, S]) bool
- func (sig *Signature[Sig, SigFE, PK, PKFE, E, S]) HashCode() base.HashCode
- func (sig *Signature[Sig, SigFE, PK, PKFE, E, S]) IsLong() bool
- func (sig *Signature[Sig, SigFE, PK, PKFE, E, S]) Pop() *ProofOfPossession[Sig, SigFE, PK, PKFE, E, S]
- func (sig *Signature[Sig, SigFE, PK, PKFE, E, S]) TryAdd(other *Signature[Sig, SigFE, PK, PKFE, E, S]) (*Signature[Sig, SigFE, PK, PKFE, E, S], error)
- func (sig *Signature[Sig, SigFE, PK, PKFE, E, S]) Value() Sig
- type Signer
- func (s *Signer[PK, PKFE, SG, SGFE, E, S]) AggregateSign(messages ...Message) (*Signature[SG, SGFE, PK, PKFE, E, S], error)
- func (s *Signer[PK, PKFE, SG, SGFE, E, S]) BatchSign(messages ...Message) ([]*Signature[SG, SGFE, PK, PKFE, E, S], error)
- func (s *Signer[PK, PKFE, SG, SGFE, E, S]) Sign(message []byte) (*Signature[SG, SGFE, PK, PKFE, E, S], error)
- type SignerOption
- type Variant
- type Verifier
- type VerifierOption
- func VerifyWithCustomDST[PK curves.PairingFriendlyPoint[PK, PKFE, SG, SGFE, E, S], ...](dst string) VerifierOption[PK, PKFE, SG, SGFE, E, S]
- func VerifyWithProofsOfPossession[PK curves.PairingFriendlyPoint[PK, PKFE, SG, SGFE, E, S], ...](pops ...*ProofOfPossession[SG, SGFE, PK, PKFE, E, S]) VerifierOption[PK, PKFE, SG, SGFE, E, S]
Constants ¶
const ( // Name is the canonical identifier for this signature scheme. Name signatures.Name = "BLS" // Basic is a rogue key prevention algorithm that protects against rogue key attacks by // requiring all messages in an aggregate signature to be distinct. // See: https://www.ietf.org/archive/id/draft-irtf-cfrg-bls-signature-06.html#section-3.1 Basic RogueKeyPreventionAlgorithm = 1 // MessageAugmentation is a rogue key prevention algorithm where signatures are computed // over the concatenation of the public key and message (pk || msg). This ensures messages // signed by different keys are inherently distinct, preventing rogue key attacks without // additional validation. // See: https://www.ietf.org/archive/id/draft-irtf-cfrg-bls-signature-06.html#section-3.2 MessageAugmentation RogueKeyPreventionAlgorithm = 2 // POP (Proof of Possession) is a rogue key prevention algorithm where signers must // provide a proof demonstrating knowledge of their secret key. This enables the optimised // FastAggregateVerify algorithm for verifying multiple signatures on identical messages. // See: https://www.ietf.org/archive/id/draft-irtf-cfrg-bls-signature-06.html#section-3.3 POP RogueKeyPreventionAlgorithm = 3 // ShortKey indicates the minimal-pubkey-size variant where public keys are points on // the G1 curve (48 bytes compressed) and signatures are points on G2 (96 bytes compressed). // This variant is preferred when public keys are transmitted more frequently than signatures. ShortKey Variant = 1 // LongKey indicates the minimal-signature-size variant where public keys are points on // the G2 curve (96 bytes compressed) and signatures are points on G1 (48 bytes compressed). // This variant is preferred when signatures are transmitted more frequently than public keys. LongKey Variant = 2 )
const HKDFKeyGenSalt = "BLS-SIG-KEYGEN-SALT-"
HKDFKeyGenSalt is the initial salt value for key generation using HKDF. Per the spec, if the initial hash produces a zero scalar, the salt is re-hashed and the process repeated until a valid non-zero key is derived.
See: https://www.ietf.org/archive/id/draft-irtf-cfrg-bls-signature-06.html#section-2.3
Variables ¶
var ( // ErrInvalidArgument indicates missing, nil, or inconsistent inputs. ErrInvalidArgument = errs.New("invalid argument") // ErrFailed indicates a general failure during protocol execution. ErrFailed = errs.New("failed") // ErrVerificationFailed signals a failed signature or proof verification. ErrVerificationFailed = errs.New("verification failed") // ErrNotSupported indicates an unsupported algorithm or variant. ErrNotSupported = errs.New("not supported") // ErrInvalidSubGroup indicates an element is not in the correct subgroup. ErrInvalidSubGroup = errs.New("invalid subgroup") )
var RandomOracleHashFunction = sha3.New256
RandomOracleHashFunction is the hash function used for key derivation. SHA3-256 is used as it models a random oracle for salt generation.
Functions ¶
func AggregateAll ¶
func AggregateAll[ PK curves.PairingFriendlyPoint[PK, PKFE, SG, SGFE, ET, S], PKFE algebra.FieldElement[PKFE], SG curves.PairingFriendlyPoint[SG, SGFE, PK, PKFE, ET, S], SGFE algebra.FieldElement[SGFE], ET algebra.MultiplicativeGroupElement[ET], S algebra.PrimeFieldElement[S], Xs ~[]X, X interface { TryAdd(other X) (X, error) }, ](xs Xs) (X, error)
AggregateAll combines multiple BLS elements (public keys, signatures, or proofs) into a single aggregate element via elliptic curve point addition.
For public keys: aggregate_pk = pk_1 + pk_2 + ... + pk_n For signatures: aggregate_sig = sig_1 + sig_2 + ... + sig_n
The aggregation is homomorphic, enabling efficient batch verification of multiple signatures. See: https://www.ietf.org/archive/id/draft-irtf-cfrg-bls-signature-06.html#section-2.8
func AugmentMessage ¶
func AugmentMessage[ PK curves.Point[PK, PKFE, S], PKFE algebra.FieldElement[PKFE], S algebra.PrimeFieldElement[S], ](message []byte, publicKey PK) ([]byte, error)
AugmentMessage prepends the serialised public key to the message for the Message Augmentation signature scheme. This creates a unique message per signer, preventing rogue key attacks without requiring additional proofs or message distinctness checks.
The augmented message is: pk || msg
See: https://www.ietf.org/archive/id/draft-irtf-cfrg-bls-signature-06.html#section-3.2.1
func RogueKeyPreventionAlgorithmIsSupported ¶
func RogueKeyPreventionAlgorithmIsSupported(alg RogueKeyPreventionAlgorithm) bool
RogueKeyPreventionAlgorithmIsSupported returns true if the given algorithm is one of the three supported rogue key prevention schemes: Basic, MessageAugmentation, or POP.
Types ¶
type CipherSuite ¶
type CipherSuite struct {
FamilyName string
DstSignatureBasicInTwistedGroup string
DstSignatureAugInTwistedGroup string
DstSignaturePopInTwistedGroup string
DstPopProofInTwistedGroup string
DstSignatureBasicInSourceGroup string
DstSignatureAugInSourceGroup string
DstSignaturePopInSourceGroup string
DstPopProofInSourceGroup string
}
CipherSuite defines the cryptographic parameters for a BLS signature scheme instance. It specifies the curve family and domain separation tags (DSTs) for hash-to-curve operations.
Domain separation tags ensure that hash outputs for different purposes (signing, POP proofs) and different curve subgroups remain cryptographically independent. The tag format follows: "BLS_SIG_<curve>_<hash>_<map>_<variant>_" for signatures and "BLS_POP_<curve>_<hash>_<map>_<variant>_" for proof of possession.
See: https://www.ietf.org/archive/id/draft-irtf-cfrg-bls-signature-06.html#section-4.2
func BLS12381CipherSuite ¶
func BLS12381CipherSuite() *CipherSuite
BLS12381CipherSuite returns the standard ciphersuite for BLS12-381 curve. It uses SHA-256 for hashing and the simplified SWU map for hash-to-curve.
The ciphersuite identifiers follow the format specified in: https://www.ietf.org/archive/id/draft-irtf-cfrg-bls-signature-06.html#section-4.2
func (*CipherSuite) GetDst ¶
func (c *CipherSuite) GetDst(alg RogueKeyPreventionAlgorithm, variant Variant) (string, error)
GetDst returns the domain separation tag for signing operations based on the rogue key prevention algorithm and key/signature variant. The DST is used in hash-to-curve operations to ensure cryptographic domain separation between different signature schemes.
func (*CipherSuite) GetPopDst ¶
func (c *CipherSuite) GetPopDst(variant Variant) string
GetPopDst returns the domain separation tag for proof of possession operations. Note: POP proofs hash the public key to the opposite subgroup from where the key lives, hence ShortKey (keys in G1) uses SourceGroup DST (hashing to G1 for POP proof).
type KeyGenerator ¶
type KeyGenerator[ PK curves.PairingFriendlyPoint[PK, FE, Sig, SigFE, E, S], FE algebra.FieldElement[FE], Sig curves.PairingFriendlyPoint[Sig, SigFE, PK, FE, E, S], SigFE algebra.FieldElement[SigFE], E algebra.MultiplicativeGroupElement[E], S algebra.PrimeFieldElement[S], ] struct { // contains filtered or unexported fields }
KeyGenerator generates BLS key pairs using the KeyGen algorithm from the specification. Key generation uses HKDF with SHA3-256 to derive secret keys from input keying material.
See: https://www.ietf.org/archive/id/draft-irtf-cfrg-bls-signature-06.html#section-2.3
func (*KeyGenerator[PK, FE, Sig, SigFE, E, S]) Generate ¶
func (kg *KeyGenerator[PK, FE, Sig, SigFE, E, S]) Generate(prng io.Reader) (*PrivateKey[PK, FE, Sig, SigFE, E, S], *PublicKey[PK, FE, Sig, SigFE, E, S], error)
Generate creates a new BLS key pair using random bytes from the provided reader. If a seed was previously set via the GenerateWithSeed option, that seed is used instead.
The prng should be a cryptographically secure random source (e.g., crypto/rand.Reader).
func (*KeyGenerator[PK, FE, Sig, SigFE, E, S]) GenerateWithSeed ¶
func (kg *KeyGenerator[PK, FE, Sig, SigFE, E, S]) GenerateWithSeed(ikm []byte) (*PrivateKey[PK, FE, Sig, SigFE, E, S], *PublicKey[PK, FE, Sig, SigFE, E, S], error)
GenerateWithSeed derives a BLS key pair from the provided input keying material (IKM). The IKM must be at least 32 bytes and should contain high-entropy random data.
This implements the KeyGen algorithm:
- Hash the salt to get initial HKDF salt
- Use HKDF-Extract and HKDF-Expand to derive key material
- Convert to scalar, re-hash salt if a result is zero
- Compute public key as sk * G
See: https://www.ietf.org/archive/id/draft-irtf-cfrg-bls-signature-06.html#section-2.3
type KeyGeneratorOption ¶
type KeyGeneratorOption[ PK curves.PairingFriendlyPoint[PK, PKFE, SG, SGFE, E, S], PKFE algebra.FieldElement[PKFE], SG curves.PairingFriendlyPoint[SG, SGFE, PK, PKFE, E, S], SGFE algebra.FieldElement[SGFE], E algebra.MultiplicativeGroupElement[E], S algebra.PrimeFieldElement[S], ] = signatures.KeyGeneratorOption[ *KeyGenerator[PK, PKFE, SG, SGFE, E, S], *PrivateKey[PK, PKFE, SG, SGFE, E, S], *PublicKey[PK, PKFE, SG, SGFE, E, S], ]
KeyGeneratorOption is a functional option for configuring a KeyGenerator.
func GenerateWithSeed ¶
func GenerateWithSeed[PK curves.PairingFriendlyPoint[PK, FE, Sig, SigFE, E, S], FE algebra.FieldElement[FE], Sig curves.PairingFriendlyPoint[Sig, SigFE, PK, FE, E, S], SigFE algebra.FieldElement[SigFE], E algebra.MultiplicativeGroupElement[E], S algebra.PrimeFieldElement[S], ](seed []byte) KeyGeneratorOption[PK, FE, Sig, SigFE, E, S]
GenerateWithSeed returns a KeyGeneratorOption that uses the provided seed for deterministic key generation instead of random sampling.
The seed must be at least as long as the scalar field element size (32 bytes for BLS12-381). Using the same seed will always produce the same key pair.
type Message ¶
type Message = []byte
Message is the type alias for message bytes to be signed or verified.
type PrivateKey ¶
type PrivateKey[ PK curves.PairingFriendlyPoint[PK, PKFE, Sig, SigFE, E, S], PKFE algebra.FieldElement[PKFE], Sig curves.PairingFriendlyPoint[Sig, SigFE, PK, PKFE, E, S], SigFE algebra.FieldElement[SigFE], E algebra.MultiplicativeGroupElement[E], S algebra.PrimeFieldElement[S], ] struct { signatures.PrivateKeyTrait[PK, S] }
PrivateKey represents a BLS secret key as a scalar in the prime field Fr. The secret key sk is an integer in [1, r-1] where r is the order of the subgroups G1 and G2.
Security: Private keys must be generated using a cryptographically secure random source and protected against side-channel attacks. The KeyGen algorithm uses HKDF for secure key derivation from random input keying material.
See: https://www.ietf.org/archive/id/draft-irtf-cfrg-bls-signature-06.html#section-2.3
func NewPrivateKey ¶
func NewPrivateKey[ PK curves.PairingFriendlyPoint[PK, PKFE, Sig, SigFE, E, S], PKFE algebra.FieldElement[PKFE], Sig curves.PairingFriendlyPoint[Sig, SigFE, PK, PKFE, E, S], SigFE algebra.FieldElement[SigFE], E algebra.MultiplicativeGroupElement[E], S algebra.PrimeFieldElement[S], ](subGroup curves.PairingFriendlyCurve[PK, PKFE, Sig, SigFE, E, S], v S) (*PrivateKey[PK, PKFE, Sig, SigFE, E, S], error)
NewPrivateKey creates a PrivateKey from a scalar value and computes the corresponding public key. The scalar must be non-zero and in the range [1, r-1] where r is the subgroup order.
The public key is derived as pk = sk * G (SkToPk operation in the spec). See: https://www.ietf.org/archive/id/draft-irtf-cfrg-bls-signature-06.html#section-2.4
func NewPrivateKeyFromBytes ¶
func NewPrivateKeyFromBytes[ PK curves.PairingFriendlyPoint[PK, PKFE, Sig, SigFE, E, S], PKFE algebra.FieldElement[PKFE], Sig curves.PairingFriendlyPoint[Sig, SigFE, PK, PKFE, E, S], SigFE algebra.FieldElement[SigFE], E algebra.MultiplicativeGroupElement[E], S algebra.PrimeFieldElement[S], ](subGroup curves.PairingFriendlyCurve[PK, PKFE, Sig, SigFE, E, S], input []byte) (*PrivateKey[PK, PKFE, Sig, SigFE, E, S], error)
NewPrivateKeyFromBytes deserializes a PrivateKey from its byte representation. The input is interpreted as a big-endian integer and validated to be non-zero.
func (*PrivateKey[PK, PKFE, Sig, SigFE, E, S]) Bytes ¶
func (sk *PrivateKey[PK, PKFE, Sig, SigFE, E, S]) Bytes() []byte
Bytes returns the little-endian byte representation of the secret key scalar. The output is 32 bytes for BLS12-381.
func (*PrivateKey[PK, PKFE, Sig, SigFE, E, S]) Clone ¶
func (sk *PrivateKey[PK, PKFE, Sig, SigFE, E, S]) Clone() *PrivateKey[PK, PKFE, Sig, SigFE, E, S]
Clone returns a deep copy of the private key.
func (*PrivateKey[PK, PKFE, Sig, SigFE, E, S]) Equal ¶
func (sk *PrivateKey[PK, PKFE, Sig, SigFE, E, S]) Equal(other *PrivateKey[PK, PKFE, Sig, SigFE, E, S]) bool
Equal returns true if both private keys have the same scalar value.
func (*PrivateKey[PK, PKFE, Sig, SigFE, E, S]) Group ¶
func (sk *PrivateKey[PK, PKFE, Sig, SigFE, E, S]) Group() curves.Curve[PK, PKFE, S]
Group returns the elliptic curve associated with this private key's public key.
func (*PrivateKey[PK, PKFE, Sig, SigFE, E, S]) Name ¶
func (*PrivateKey[PK, PKFE, Sig, SigFE, E, S]) Name() signatures.Name
Name returns the signature scheme identifier ("BLS").
func (*PrivateKey[PK, PKFE, Sig, SigFE, E, S]) PublicKey ¶
func (sk *PrivateKey[PK, PKFE, Sig, SigFE, E, S]) PublicKey() *PublicKey[PK, PKFE, Sig, SigFE, E, S]
PublicKey returns the public key corresponding to this private key. The public key is computed as pk = sk * G during key creation.
type ProofOfPossession ¶
type ProofOfPossession[ Sig curves.PairingFriendlyPoint[Sig, SigFE, PK, PKFE, E, S], SigFE algebra.FieldElement[SigFE], PK curves.PairingFriendlyPoint[PK, PKFE, Sig, SigFE, E, S], PKFE algebra.FieldElement[PKFE], E algebra.MultiplicativeGroupElement[E], S algebra.PrimeFieldElement[S], ] struct { Signature[Sig, SigFE, PK, PKFE, E, S] }
ProofOfPossession is a cryptographic proof that the holder of a public key knows the corresponding secret key. It prevents rogue key attacks in signature aggregation by requiring each participant to prove key ownership before their signatures are aggregated.
The proof is verified using: e(pk, H(pk)) = e(G, pop) where H uses a domain separation tag distinct from signature generation.
Proofs can be aggregated when verifying multiple signatures on the same message, enabling the efficient FastAggregateVerify algorithm.
See: https://www.ietf.org/archive/id/draft-irtf-cfrg-bls-signature-06.html#section-3.3
func NewProofOfPossession ¶
func NewProofOfPossession[ Sig curves.PairingFriendlyPoint[Sig, SigFE, PK, PKFE, E, S], SigFE algebra.FieldElement[SigFE], PK curves.PairingFriendlyPoint[PK, PKFE, Sig, SigFE, E, S], PKFE algebra.FieldElement[PKFE], E algebra.MultiplicativeGroupElement[E], S algebra.PrimeFieldElement[S], ](v Sig) (*ProofOfPossession[Sig, SigFE, PK, PKFE, E, S], error)
NewProofOfPossession creates a ProofOfPossession from an elliptic curve point. A proof of possession is a signature on the public key itself, demonstrating that the signer knows the corresponding secret key.
The proof is generated as: pop = sk * H(pk) where H hashes to the signature subgroup using a distinct domain separation tag from regular signatures.
See: https://www.ietf.org/archive/id/draft-irtf-cfrg-bls-signature-06.html#section-3.3.2
func NewProofOfPossessionFromBytes ¶
func NewProofOfPossessionFromBytes[ Sig curves.PairingFriendlyPoint[Sig, SigFE, PK, PKFE, E, S], SigFE algebra.FieldElement[SigFE], PK curves.PairingFriendlyPoint[PK, PKFE, Sig, SigFE, E, S], PKFE algebra.FieldElement[PKFE], E algebra.MultiplicativeGroupElement[E], S algebra.PrimeFieldElement[S], ](subGroup curves.PairingFriendlyCurve[Sig, SigFE, PK, PKFE, E, S], input []byte) (*ProofOfPossession[Sig, SigFE, PK, PKFE, E, S], error)
NewProofOfPossessionFromBytes deserializes a ProofOfPossession from its compressed byte representation. The input is validated to ensure it represents a valid curve point in the correct subgroup.
func (*ProofOfPossession[Sig, SigFE, PK, PKFE, E, S]) Bytes ¶
func (pop *ProofOfPossession[Sig, SigFE, PK, PKFE, E, S]) Bytes() []byte
Bytes returns the compressed serialisation of the proof of possession.
func (*ProofOfPossession[Sig, SigFE, PK, PKFE, E, S]) Clone ¶
func (pop *ProofOfPossession[Sig, SigFE, PK, PKFE, E, S]) Clone() *ProofOfPossession[Sig, SigFE, PK, PKFE, E, S]
Clone returns a deep copy of the proof of possession.
func (*ProofOfPossession[Sig, SigFE, PK, PKFE, E, S]) Equal ¶
func (pop *ProofOfPossession[Sig, SigFE, PK, PKFE, E, S]) Equal(other *ProofOfPossession[Sig, SigFE, PK, PKFE, E, S]) bool
Equal returns true if both proofs represent the same curve point.
func (*ProofOfPossession[Sig, SigFE, PK, PKFE, E, S]) HashCode ¶
func (pop *ProofOfPossession[Sig, SigFE, PK, PKFE, E, S]) HashCode() base.HashCode
HashCode returns a hash of the proof for use in hash-based data structures.
func (*ProofOfPossession[Sig, SigFE, PK, PKFE, E, S]) TryAdd ¶
func (pop *ProofOfPossession[Sig, SigFE, PK, PKFE, E, S]) TryAdd(other *ProofOfPossession[Sig, SigFE, PK, PKFE, E, S]) (*ProofOfPossession[Sig, SigFE, PK, PKFE, E, S], error)
TryAdd aggregates this proof of possession with another by elliptic curve point addition. Used when aggregating signatures that each have attached proofs.
func (*ProofOfPossession[Sig, SigFE, PK, PKFE, E, S]) Value ¶
func (pop *ProofOfPossession[Sig, SigFE, PK, PKFE, E, S]) Value() Sig
Value returns the underlying curve point of the proof.
type PublicKey ¶
type PublicKey[ PK curves.PairingFriendlyPoint[PK, PKFE, Sig, SigFE, E, S], PKFE algebra.FieldElement[PKFE], Sig curves.PairingFriendlyPoint[Sig, SigFE, PK, PKFE, E, S], SigFE algebra.FieldElement[SigFE], E algebra.MultiplicativeGroupElement[E], S algebra.PrimeFieldElement[S], ] struct { signatures.PublicKeyTrait[PK, S] }
PublicKey represents a BLS public key as a point on a pairing-friendly elliptic curve. The public key is computed as pk = sk * G, where sk is the secret key scalar and G is the generator of the chosen subgroup (G1 for ShortKey variant, G2 for LongKey).
Public keys can be aggregated via elliptic curve point addition to form aggregate public keys for multi-signature verification.
See: https://www.ietf.org/archive/id/draft-irtf-cfrg-bls-signature-06.html#section-2.4
func NewPublicKey ¶
func NewPublicKey[ PK curves.PairingFriendlyPoint[PK, PKFE, Sig, SigFE, E, S], PKFE algebra.FieldElement[PKFE], Sig curves.PairingFriendlyPoint[Sig, SigFE, PK, PKFE, E, S], SigFE algebra.FieldElement[SigFE], E algebra.MultiplicativeGroupElement[E], S algebra.PrimeFieldElement[S], ](v PK) (*PublicKey[PK, PKFE, Sig, SigFE, E, S], error)
NewPublicKey creates a PublicKey from an elliptic curve point. The point must be a valid, non-identity element in the correct prime-order subgroup.
Security: Validates that the point is not the identity element and is torsion-free (lies in the prime-order subgroup). This prevents invalid key attacks. See: https://www.ietf.org/archive/id/draft-irtf-cfrg-bls-signature-06.html#section-2.5
func NewPublicKeyFromBytes ¶
func NewPublicKeyFromBytes[ PK curves.PairingFriendlyPoint[PK, PKFE, Sig, SigFE, E, S], PKFE algebra.FieldElement[PKFE], Sig curves.PairingFriendlyPoint[Sig, SigFE, PK, PKFE, E, S], SigFE algebra.FieldElement[SigFE], E algebra.MultiplicativeGroupElement[E], S algebra.PrimeFieldElement[S], ](subGroup curves.PairingFriendlyCurve[PK, PKFE, Sig, SigFE, E, S], input []byte) (*PublicKey[PK, PKFE, Sig, SigFE, E, S], error)
NewPublicKeyFromBytes deserializes a PublicKey from its compressed byte representation. The input is validated to ensure it represents a valid curve point in the correct subgroup.
func (*PublicKey[P1, F1, P2, F2, E, S]) Bytes ¶
Bytes returns the compressed serialisation of the public key. For ShortKey variant (G1): 48 bytes. For LongKey variant (G2): 96 bytes.
func (*PublicKey[P1, F1, P2, F2, E, S]) Equal ¶
Equal returns true if both public keys represent the same curve point.
func (*PublicKey[P1, F1, P2, F2, E, S]) Group ¶
func (pk *PublicKey[P1, F1, P2, F2, E, S]) Group() curves.PairingFriendlyCurve[P1, F1, P2, F2, E, S]
Group returns the elliptic curve subgroup that this public key belongs to.
func (*PublicKey[P1, F1, P2, F2, E, S]) HashCode ¶
HashCode returns a hash of the public key for use in hash-based data structures.
func (*PublicKey[P1, F1, P2, F2, E, S]) IsShort ¶
IsShort returns true if this is a minimal-pubkey-size key (residing in G1).
func (*PublicKey[P1, F1, P2, F2, E, S]) Name ¶
func (*PublicKey[P1, F1, P2, F2, E, S]) Name() signatures.Name
Name returns the signature scheme identifier ("BLS").
func (*PublicKey[P1, F1, P2, F2, E, S]) TryAdd ¶
func (pk *PublicKey[P1, F1, P2, F2, E, S]) TryAdd(other *PublicKey[P1, F1, P2, F2, E, S]) (*PublicKey[P1, F1, P2, F2, E, S], error)
TryAdd aggregates this public key with another by elliptic curve point addition. The result can be used as an aggregate public key for verifying aggregate signatures. Returns an error if other is nil, the identity element, or not in the correct subgroup.
type RogueKeyPreventionAlgorithm ¶
type RogueKeyPreventionAlgorithm int
RogueKeyPreventionAlgorithm specifies the scheme used to prevent rogue key attacks in BLS signature aggregation. A rogue key attack occurs when an adversary creates a malicious public key that cancels out honest signers' contributions in an aggregate signature.
type Scheme ¶
type Scheme[ PK curves.PairingFriendlyPoint[PK, PKFE, SG, SGFE, E, S], PKFE algebra.FieldElement[PKFE], SG curves.PairingFriendlyPoint[SG, SGFE, PK, PKFE, E, S], SGFE algebra.FieldElement[SGFE], E algebra.MultiplicativeGroupElement[E], S algebra.PrimeFieldElement[S], ] struct { // contains filtered or unexported fields }
Scheme represents a configured BLS signature scheme instance with a specific curve family, key/signature variant, and rogue key prevention algorithm.
The Scheme provides factory methods for creating key generators, signers, and verifiers, as well as signature aggregation functionality.
func NewLongKeyScheme ¶
func NewLongKeyScheme[ P1 curves.PairingFriendlyPoint[P1, FE1, P2, FE2, E, S], FE1 algebra.FieldElement[FE1], P2 curves.PairingFriendlyPoint[P2, FE2, P1, FE1, E, S], FE2 algebra.FieldElement[FE2], E algebra.MultiplicativeGroupElement[E], S algebra.PrimeFieldElement[S], ](curveFamily curves.PairingFriendlyFamily[P1, FE1, P2, FE2, E, S], rogueKeyAlg RogueKeyPreventionAlgorithm) (*Scheme[P2, FE2, P1, FE1, E, S], error)
NewLongKeyScheme creates a BLS signature scheme with minimal signature size. Public keys reside in G2 (96 bytes compressed) and signatures in G1 (48 bytes compressed).
This variant is preferred when signatures are transmitted or stored more frequently than public keys, as the smaller signature size reduces bandwidth and storage costs.
The rogueKeyAlg parameter specifies the rogue key attack prevention mechanism:
- Basic: requires distinct messages in aggregate signatures
- MessageAugmentation: prepends public key to messages before signing
- POP: requires proof of possession for each public key
func NewShortKeyScheme ¶
func NewShortKeyScheme[ P1 curves.PairingFriendlyPoint[P1, FE1, P2, FE2, E, S], FE1 algebra.FieldElement[FE1], P2 curves.PairingFriendlyPoint[P2, FE2, P1, FE1, E, S], FE2 algebra.FieldElement[FE2], E algebra.MultiplicativeGroupElement[E], S algebra.PrimeFieldElement[S], ](curveFamily curves.PairingFriendlyFamily[P1, FE1, P2, FE2, E, S], rogueKeyAlg RogueKeyPreventionAlgorithm) (*Scheme[P1, FE1, P2, FE2, E, S], error)
NewShortKeyScheme creates a BLS signature scheme with minimal public key size. Public keys reside in G1 (48 bytes compressed) and signatures in G2 (96 bytes compressed).
This variant is preferred when public keys are transmitted or stored more frequently than signatures, as the smaller key size reduces bandwidth and storage costs.
The rogueKeyAlg parameter specifies the rogue key attack prevention mechanism:
- Basic: requires distinct messages in aggregate signatures
- MessageAugmentation: prepends public key to messages before signing
- POP: requires proof of possession for each public key
func (*Scheme[PK, PKFE, SG, SGFE, E, S]) AggregateSignatures ¶
func (*Scheme[PK, PKFE, SG, SGFE, E, S]) AggregateSignatures(sigs ...*Signature[SG, SGFE, PK, PKFE, E, S]) (*Signature[SG, SGFE, PK, PKFE, E, S], error)
AggregateSignatures combines multiple BLS signatures into a single aggregate signature via elliptic curve point addition. The resulting signature can be verified against the corresponding aggregate public key or set of public keys.
See: https://www.ietf.org/archive/id/draft-irtf-cfrg-bls-signature-06.html#section-2.8
func (*Scheme[PK, PKFE, SG, SGFE, E, S]) CipherSuite ¶
func (s *Scheme[PK, PKFE, SG, SGFE, E, S]) CipherSuite() *CipherSuite
CipherSuite returns the cryptographic parameters including domain separation tags for hash-to-curve operations.
func (*Scheme[PK, PKFE, SG, SGFE, E, S]) KeySubGroup ¶
func (s *Scheme[PK, PKFE, SG, SGFE, E, S]) KeySubGroup() curves.PairingFriendlyCurve[PK, PKFE, SG, SGFE, E, S]
KeySubGroup returns the elliptic curve subgroup used for public keys. For ShortKey: G1. For LongKey: G2.
func (*Scheme[PK, PKFE, SG, SGFE, E, S]) Keygen ¶
func (s *Scheme[PK, PKFE, SG, SGFE, E, S]) Keygen(opts ...KeyGeneratorOption[PK, PKFE, SG, SGFE, E, S]) (*KeyGenerator[PK, PKFE, SG, SGFE, E, S], error)
Keygen creates a key generator for producing BLS key pairs. Options can be used to provide deterministic seed material.
See: https://www.ietf.org/archive/id/draft-irtf-cfrg-bls-signature-06.html#section-2.3
func (*Scheme[PK, PKFE, SG, SGFE, E, S]) Name ¶
func (*Scheme[PK, PKFE, SG, SGFE, E, S]) Name() signatures.Name
Name returns the signature scheme identifier ("BLS").
func (*Scheme[PK, PKFE, SG, SGFE, E, S]) RogueKeyPreventionAlgorithm ¶
func (s *Scheme[PK, PKFE, SG, SGFE, E, S]) RogueKeyPreventionAlgorithm() RogueKeyPreventionAlgorithm
RogueKeyPreventionAlgorithm returns the rogue key attack prevention mechanism configured for this scheme (Basic, MessageAugmentation, or POP).
func (*Scheme[PK, PKFE, SG, SGFE, E, S]) SignatureSubGroup ¶
func (s *Scheme[PK, PKFE, SG, SGFE, E, S]) SignatureSubGroup() curves.PairingFriendlyCurve[SG, SGFE, PK, PKFE, E, S]
SignatureSubGroup returns the elliptic curve subgroup used for signatures. For ShortKey: G2. For LongKey: G1.
func (*Scheme[PK, PKFE, SG, SGFE, E, S]) Signer ¶
func (s *Scheme[PK, PKFE, SG, SGFE, E, S]) Signer(privateKey *PrivateKey[PK, PKFE, SG, SGFE, E, S], opts ...SignerOption[PK, PKFE, SG, SGFE, E, S]) (*Signer[PK, PKFE, SG, SGFE, E, S], error)
Signer creates a signer for producing BLS signatures with the given private key. Options can be used to customise the domain separation tag.
See: https://www.ietf.org/archive/id/draft-irtf-cfrg-bls-signature-06.html#section-2.6
func (*Scheme[PK, PKFE, SG, SGFE, E, S]) Variant ¶
Variant returns whether this scheme uses minimal public key size (ShortKey) or minimal signature size (LongKey).
func (*Scheme[PK, PKFE, SG, SGFE, E, S]) Verifier ¶
func (s *Scheme[PK, PKFE, SG, SGFE, E, S]) Verifier(opts ...VerifierOption[PK, PKFE, SG, SGFE, E, S]) (*Verifier[PK, PKFE, SG, SGFE, E, S], error)
Verifier creates a verifier for validating BLS signatures. Options can be used to customise the domain separation tag or provide proofs of possession.
See: https://www.ietf.org/archive/id/draft-irtf-cfrg-bls-signature-06.html#section-2.7
type Signature ¶
type Signature[ Sig curves.PairingFriendlyPoint[Sig, SigFE, PK, PKFE, E, S], SigFE algebra.FieldElement[SigFE], PK curves.PairingFriendlyPoint[PK, PKFE, Sig, SigFE, E, S], PKFE algebra.FieldElement[PKFE], E algebra.MultiplicativeGroupElement[E], S algebra.PrimeFieldElement[S], ] struct { // contains filtered or unexported fields }
Signature represents a BLS signature as a point on a pairing-friendly elliptic curve. The signature is computed as sig = sk * H(m), where sk is the secret key and H(m) is the hash-to-curve output for message m.
Signatures can be aggregated via elliptic curve point addition. When using the POP scheme, signatures may include an attached proof of possession.
Verification uses the pairing equation: e(pk, H(m)) = e(G, sig) See: https://www.ietf.org/archive/id/draft-irtf-cfrg-bls-signature-06.html#section-2.6
func NewSignature ¶
func NewSignature[ Sig curves.PairingFriendlyPoint[Sig, SigFE, PK, PKFE, E, S], SigFE algebra.FieldElement[SigFE], PK curves.PairingFriendlyPoint[PK, PKFE, Sig, SigFE, E, S], PKFE algebra.FieldElement[PKFE], E algebra.MultiplicativeGroupElement[E], S algebra.PrimeFieldElement[S], ](v Sig, pop *ProofOfPossession[Sig, SigFE, PK, PKFE, E, S]) (*Signature[Sig, SigFE, PK, PKFE, E, S], error)
NewSignature creates a Signature from an elliptic curve point, optionally with a proof of possession. The point must be a valid, non-identity element in the correct prime-order subgroup.
Security: Validates subgroup membership to prevent attacks exploiting small subgroup elements. See: https://www.ietf.org/archive/id/draft-irtf-cfrg-bls-signature-06.html#section-2.5
func NewSignatureFromBytes ¶
func NewSignatureFromBytes[ Sig curves.PairingFriendlyPoint[Sig, SigFE, PK, PKFE, E, S], SigFE algebra.FieldElement[SigFE], PK curves.PairingFriendlyPoint[PK, PKFE, Sig, SigFE, E, S], PKFE algebra.FieldElement[PKFE], E algebra.MultiplicativeGroupElement[E], S algebra.PrimeFieldElement[S], ](subGroup curves.PairingFriendlyCurve[Sig, SigFE, PK, PKFE, E, S], input []byte, pop *ProofOfPossession[Sig, SigFE, PK, PKFE, E, S]) (*Signature[Sig, SigFE, PK, PKFE, E, S], error)
NewSignatureFromBytes deserializes a Signature from its compressed byte representation. The input is validated to ensure it represents a valid curve point in the correct subgroup.
func (*Signature[Sig, SigFE, PK, PKFE, E, S]) Bytes ¶
Bytes returns the compressed serialisation of the signature. For ShortKey variant (sig in G2): 96 bytes. For LongKey variant (sig in G1): 48 bytes.
func (*Signature[Sig, SigFE, PK, PKFE, E, S]) Clone ¶
Clone returns a deep copy of the signature including any attached proof of possession.
func (*Signature[Sig, SigFE, PK, PKFE, E, S]) Equal ¶
func (sig *Signature[Sig, SigFE, PK, PKFE, E, S]) Equal(other *Signature[Sig, SigFE, PK, PKFE, E, S]) bool
Equal returns true if both signatures represent the same curve point and have equal POPs.
func (*Signature[Sig, SigFE, PK, PKFE, E, S]) HashCode ¶
HashCode returns a hash of the signature for use in hash-based data structures.
func (*Signature[Sig, SigFE, PK, PKFE, E, S]) IsLong ¶
IsLong returns true if this is a minimal-signature-size signature (residing in G1).
func (*Signature[Sig, SigFE, PK, PKFE, E, S]) Pop ¶
func (sig *Signature[Sig, SigFE, PK, PKFE, E, S]) Pop() *ProofOfPossession[Sig, SigFE, PK, PKFE, E, S]
Pop returns the attached proof of possession, or nil if none is attached. Only signatures created with the POP rogue key prevention algorithm have attached proofs.
func (*Signature[Sig, SigFE, PK, PKFE, E, S]) TryAdd ¶
func (sig *Signature[Sig, SigFE, PK, PKFE, E, S]) TryAdd(other *Signature[Sig, SigFE, PK, PKFE, E, S]) (*Signature[Sig, SigFE, PK, PKFE, E, S], error)
TryAdd aggregates this signature with another by elliptic curve point addition. If both signatures have proofs of possession, those are also aggregated. Returns an error if other is nil, the identity element, or not in the correct subgroup.
See: https://www.ietf.org/archive/id/draft-irtf-cfrg-bls-signature-06.html#section-2.8
type Signer ¶
type Signer[ PK curves.PairingFriendlyPoint[PK, PKFE, SG, SGFE, E, S], PKFE algebra.FieldElement[PKFE], SG curves.PairingFriendlyPoint[SG, SGFE, PK, PKFE, E, S], SGFE algebra.FieldElement[SGFE], E algebra.MultiplicativeGroupElement[E], S algebra.PrimeFieldElement[S], ] struct { // contains filtered or unexported fields }
Signer produces BLS signatures using the CoreSign algorithm. The signing behaviour depends on the configured rogue key prevention algorithm:
- Basic: signs the message directly
- MessageAugmentation: signs pk || message
- POP: signs the message and attaches a proof of possession
See: https://www.ietf.org/archive/id/draft-irtf-cfrg-bls-signature-06.html#section-2.6
func (*Signer[PK, PKFE, SG, SGFE, E, S]) AggregateSign ¶
func (s *Signer[PK, PKFE, SG, SGFE, E, S]) AggregateSign(messages ...Message) (*Signature[SG, SGFE, PK, PKFE, E, S], error)
AggregateSign creates a single aggregate signature over multiple messages using the same key. This is more efficient than signing each message individually and then aggregating.
The resulting signature can be verified against the signer's public key and all messages.
func (*Signer[PK, PKFE, SG, SGFE, E, S]) BatchSign ¶
func (s *Signer[PK, PKFE, SG, SGFE, E, S]) BatchSign(messages ...Message) ([]*Signature[SG, SGFE, PK, PKFE, E, S], error)
BatchSign creates individual signatures for each message in parallel. Returns a slice of signatures, one per message, in the same order as the input.
This is useful when you need separate signatures that can be independently verified or selectively aggregated later.
func (*Signer[PK, PKFE, SG, SGFE, E, S]) Sign ¶
func (s *Signer[PK, PKFE, SG, SGFE, E, S]) Sign(message []byte) (*Signature[SG, SGFE, PK, PKFE, E, S], error)
Sign creates a BLS signature on the given message. The signature is computed as: sig = sk * H(msg) where H is hash-to-curve.
For MessageAugmentation scheme, the public key is prepended to the message. For POP scheme, a proof of possession is attached to the signature.
See: https://www.ietf.org/archive/id/draft-irtf-cfrg-bls-signature-06.html#section-2.6
type SignerOption ¶
type SignerOption[ PK curves.PairingFriendlyPoint[PK, PKFE, SG, SGFE, E, S], PKFE algebra.FieldElement[PKFE], SG curves.PairingFriendlyPoint[SG, SGFE, PK, PKFE, E, S], SGFE algebra.FieldElement[SGFE], E algebra.MultiplicativeGroupElement[E], S algebra.PrimeFieldElement[S], ] = signatures.SignerOption[ *Signer[PK, PKFE, SG, SGFE, E, S], []byte, *Signature[SG, SGFE, PK, PKFE, E, S], ]
SignerOption is a functional option for configuring a Signer.
func SignWithCustomDST ¶
func SignWithCustomDST[ PK curves.PairingFriendlyPoint[PK, PKFE, SG, SGFE, E, S], PKFE algebra.FieldElement[PKFE], SG curves.PairingFriendlyPoint[SG, SGFE, PK, PKFE, E, S], SGFE algebra.FieldElement[SGFE], E algebra.MultiplicativeGroupElement[E], S algebra.PrimeFieldElement[S], ](dst string) SignerOption[PK, PKFE, SG, SGFE, E, S]
SignWithCustomDST returns a SignerOption that overrides the default domain separation tag for hash-to-curve operations. This allows interoperability with systems using non-standard DSTs.
Warning: Using non-standard DSTs may break compatibility with other BLS implementations.
type Variant ¶
type Variant int
Variant specifies whether to use minimal public key size (ShortKey) or minimal signature size (LongKey). The choice determines which curve subgroup is used for keys vs signatures.
type Verifier ¶
type Verifier[ PK curves.PairingFriendlyPoint[PK, PKFE, SG, SGFE, E, S], PKFE algebra.FieldElement[PKFE], SG curves.PairingFriendlyPoint[SG, SGFE, PK, PKFE, E, S], SGFE algebra.FieldElement[SGFE], E algebra.MultiplicativeGroupElement[E], S algebra.PrimeFieldElement[S], ] struct { // contains filtered or unexported fields }
Verifier validates BLS signatures using the CoreVerify algorithm. Verification uses the pairing equation to check: e(pk, H(m)) = e(G, sig)
The verification behaviour depends on the rogue key prevention algorithm:
- Basic: verifies signature directly
- MessageAugmentation: reconstructs pk || message before verification
- POP: verifies attached proof of possession before signature verification
See: https://www.ietf.org/archive/id/draft-irtf-cfrg-bls-signature-06.html#section-2.7
func (*Verifier[PK, PKFE, SG, SGFE, E, S]) AggregateVerify ¶
func (v *Verifier[PK, PKFE, SG, SGFE, E, S]) AggregateVerify(signature *Signature[SG, SGFE, PK, PKFE, E, S], publicKeys []*PublicKey[PK, PKFE, SG, SGFE, E, S], messages []Message) error
AggregateVerify validates an aggregate signature against multiple public keys and messages. The verification behaviour depends on the rogue key prevention algorithm:
- Basic: requires all messages to be distinct to prevent rogue key attacks
- MessageAugmentation: augments each message with its corresponding public key
- POP: requires valid proofs of possession for each public key (via VerifyWithProofsOfPossession)
When all messages are identical and using the POP scheme, the optimised FastAggregateVerify algorithm is used, which aggregates public keys before verification.
See: https://www.ietf.org/archive/id/draft-irtf-cfrg-bls-signature-06.html#section-2.9
func (*Verifier[PK, PKFE, SG, SGFE, E, S]) Verify ¶
func (v *Verifier[PK, PKFE, SG, SGFE, E, S]) Verify(signature *Signature[SG, SGFE, PK, PKFE, E, S], publicKey *PublicKey[PK, PKFE, SG, SGFE, E, S], message Message) error
Verify validates a BLS signature against a public key and message.
The verification uses an optimised pairing check: e(pk^-1, H(m)) * e(G, sig) = 1 which reduces the number of Miller loop iterations.
Security: Validates that both the public key and signature are valid non-identity points in their respective prime-order subgroups before performing verification.
See: https://www.ietf.org/archive/id/draft-irtf-cfrg-bls-signature-06.html#section-2.7
type VerifierOption ¶
type VerifierOption[ PK curves.PairingFriendlyPoint[PK, PKFE, SG, SGFE, E, S], PKFE algebra.FieldElement[PKFE], SG curves.PairingFriendlyPoint[SG, SGFE, PK, PKFE, E, S], SGFE algebra.FieldElement[SGFE], E algebra.MultiplicativeGroupElement[E], S algebra.PrimeFieldElement[S], ] = signatures.VerifierOption[ *Verifier[PK, PKFE, SG, SGFE, E, S], *PublicKey[PK, PKFE, SG, SGFE, E, S], []byte, *Signature[SG, SGFE, PK, PKFE, E, S], ]
VerifierOption is a functional option for configuring a Verifier.
func VerifyWithCustomDST ¶
func VerifyWithCustomDST[ PK curves.PairingFriendlyPoint[PK, PKFE, SG, SGFE, E, S], PKFE algebra.FieldElement[PKFE], SG curves.PairingFriendlyPoint[SG, SGFE, PK, PKFE, E, S], SGFE algebra.FieldElement[SGFE], E algebra.MultiplicativeGroupElement[E], S algebra.PrimeFieldElement[S], ](dst string) VerifierOption[PK, PKFE, SG, SGFE, E, S]
VerifyWithCustomDST returns a VerifierOption that overrides the default domain separation tag. The DST must match the one used during signing for verification to succeed.
Warning: Using non-standard DSTs may break compatibility with other BLS implementations.
func VerifyWithProofsOfPossession ¶
func VerifyWithProofsOfPossession[ PK curves.PairingFriendlyPoint[PK, PKFE, SG, SGFE, E, S], PKFE algebra.FieldElement[PKFE], SG curves.PairingFriendlyPoint[SG, SGFE, PK, PKFE, E, S], SGFE algebra.FieldElement[SGFE], E algebra.MultiplicativeGroupElement[E], S algebra.PrimeFieldElement[S], ](pops ...*ProofOfPossession[SG, SGFE, PK, PKFE, E, S]) VerifierOption[PK, PKFE, SG, SGFE, E, S]
VerifyWithProofsOfPossession returns a VerifierOption that provides pre-validated proofs of possession for aggregate signature verification. This is required for AggregateVerify when using the POP rogue key prevention scheme.
The number of proofs must match the number of public keys in the verification.