usernames

package
v0.5.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 1, 2026 License: AGPL-3.0 Imports: 10 Imported by: 0

Documentation

Overview

Package usernames implements Signal username validation and username links.

It is a pure-Go port of the non-zk parts of upstream libsignal rust/usernames at v0.96.4. Username hash/proof APIs require the upstream poksho/Ristretto proof stack and are intentionally not exposed here yet.

Index

Constants

View Source
const (

	// LinkEntropySize is the byte length of username-link entropy.
	LinkEntropySize = 32
)

Variables

View Source
var (
	// ErrMissingSeparator reports a username without a "." separator.
	ErrMissingSeparator = errors.New("username must contain a separator")
	// ErrNicknameCannotBeEmpty reports an empty username nickname.
	ErrNicknameCannotBeEmpty = errors.New("nickname cannot be empty")
	// ErrNicknameCannotStartWithDigit reports a nickname beginning with a digit.
	ErrNicknameCannotStartWithDigit = errors.New("nickname cannot start with digit")
	// ErrBadNicknameCharacter reports a nickname containing a disallowed character.
	ErrBadNicknameCharacter = errors.New("bad nickname character")
	// ErrNicknameTooShort reports a nickname below the configured soft minimum.
	ErrNicknameTooShort = errors.New("nickname too short")
	// ErrNicknameTooLong reports a nickname above the configured soft or hard maximum.
	ErrNicknameTooLong = errors.New("nickname too long")
	// ErrDiscriminatorCannotBeEmpty reports an empty discriminator.
	ErrDiscriminatorCannotBeEmpty = errors.New("discriminator cannot be empty")
	// ErrDiscriminatorCannotBeZero reports a zero discriminator.
	ErrDiscriminatorCannotBeZero = errors.New("discriminator cannot be zero")
	// ErrDiscriminatorCannotBeSingleDigit reports a single-digit discriminator.
	ErrDiscriminatorCannotBeSingleDigit = errors.New("discriminator cannot be a single digit")
	// ErrDiscriminatorCannotHaveLeadingZeros reports a multi-digit discriminator with leading zeros.
	ErrDiscriminatorCannotHaveLeadingZeros = errors.New("discriminator cannot have leading zeros")
	// ErrBadDiscriminatorCharacter reports a discriminator containing non-digits.
	ErrBadDiscriminatorCharacter = errors.New("bad discriminator character")
	// ErrDiscriminatorTooLarge reports a discriminator too large for uint64.
	ErrDiscriminatorTooLarge = errors.New("discriminator too large")

	// ErrInputDataTooLong reports username-link plaintext that exceeds Signal's four-block bound.
	ErrInputDataTooLong = errors.New("username link input data too long")
	// ErrInvalidEntropyDataLength reports entropy that is not LinkEntropySize bytes.
	ErrInvalidEntropyDataLength = errors.New("invalid username link entropy length")
	// ErrUsernameLinkDataTooShort reports encrypted username-link data missing IV/ciphertext/HMAC.
	ErrUsernameLinkDataTooShort = errors.New("username link data too short")
	// ErrHMACMismatch reports a username-link authentication failure.
	ErrHMACMismatch = errors.New("username link hmac mismatch")
	// ErrBadCiphertext reports username-link ciphertext that fails AES-CBC decryption.
	ErrBadCiphertext = errors.New("bad username link ciphertext")
	// ErrInvalidDecryptedDataStructure reports username-link plaintext that is not valid UsernameData.
	ErrInvalidDecryptedDataStructure = errors.New("invalid username link decrypted data")
)

Functions

func CandidatesFrom

func CandidatesFrom(nickname string, limits NicknameLimits) ([]string, error)

CandidatesFrom returns randomized candidate usernames for nickname.

func CandidatesFromReader

func CandidatesFromReader(r io.Reader, nickname string, limits NicknameLimits) ([]string, error)

CandidatesFromReader returns randomized candidate usernames for nickname using r.

func DecryptUsername

func DecryptUsername(entropy [LinkEntropySize]byte, encryptedUsername []byte) (string, error)

DecryptUsername decrypts encryptedUsername with entropy and returns the username.

Types

type Link struct {
	Entropy           [LinkEntropySize]byte
	EncryptedUsername []byte
}

Link contains a username-link entropy/ciphertext pair.

func CreateLink(username string, entropy *[LinkEntropySize]byte) (Link, error)

CreateLink creates an encrypted username link using crypto/rand.

func CreateLinkFromReader

func CreateLinkFromReader(r io.Reader, username string, entropy *[LinkEntropySize]byte) (Link, error)

CreateLinkFromReader creates an encrypted username link using r for entropy and IV bytes.

func ParseLinkBuffer

func ParseLinkBuffer(buf []byte) (Link, error)

ParseLinkBuffer parses the bridge-compatible entropy||encrypted_username form.

func (Link) Buffer

func (l Link) Buffer() []byte

Buffer returns the bridge-compatible entropy||encrypted_username form.

type NicknameLimits

type NicknameLimits struct {
	Min int
	Max int
}

NicknameLimits defines the soft nickname length bounds for validation.

func DefaultNicknameLimits

func DefaultNicknameLimits() NicknameLimits

DefaultNicknameLimits returns Signal's default 3..32 nickname limits.

func NewNicknameLimits

func NewNicknameLimits(minLen, maxLen int) NicknameLimits

NewNicknameLimits constructs nickname limits, panicking for invalid bounds.

func (NicknameLimits) Validate

func (l NicknameLimits) Validate(n int) error

Validate checks n against the configured nickname length bounds.

type Username

type Username struct {
	// contains filtered or unexported fields
}

Username is a parsed Signal username.

func FromParts

func FromParts(nickname, discriminator string, limits NicknameLimits) (Username, error)

FromParts validates and parses a nickname/discriminator pair.

func Parse

func Parse(s string) (Username, error)

Parse validates and parses a full username such as "signal.42".

func (Username) Discriminator

func (u Username) Discriminator() uint64

Discriminator returns the numeric username discriminator.

func (Username) Nickname

func (u Username) Nickname() string

Nickname returns the username nickname with original casing.

func (Username) String

func (u Username) String() string

String formats the username, preserving nickname casing and two-digit minimum discriminators.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL