core

package
v0.0.16 Latest Latest
Warning

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

Go to latest
Published: Feb 26, 2026 License: Apache-2.0 Imports: 28 Imported by: 0

Documentation

Overview

Package core provides shared cryptographic and data handling functions that work in both CLI and WASM environments.

Index

Constants

View Source
const (
	// MaxFileSize is the maximum size of a single file during extraction (100 MB).
	MaxFileSize = 100 * 1024 * 1024
	// MaxTotalSize is the maximum total size of all extracted files (1 GB).
	MaxTotalSize = 1024 * 1024 * 1024
)
View Source
const (
	ShareBegin = "-----BEGIN REMEMORY SHARE-----"
	ShareEnd   = "-----END REMEMORY SHARE-----"

	// DefaultRecoveryURL is the default base URL for QR codes in PDFs.
	// Points to the recover.html hosted on GitHub Pages.
	DefaultRecoveryURL = "https://eljojo.github.io/rememory/recover.html"
)
View Source
const (
	QuicknetChainHash = "52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971"
	QuicknetPeriod    = 3 * time.Second
	QuicknetGenesis   = 1692803367 // Unix timestamp: 2023-08-23T11:22:47Z
	QuicknetPublicKey = ""         /* 192-byte string literal not displayed */

	// Additional quicknet chain info needed by the offline drand client.
	// These let the browser encrypt for a future round without any HTTP calls.
	QuicknetSchemeID  = "bls-unchained-g1-rfc9380"
	QuicknetGroupHash = "f477d5c89f21a17c863a7f937c6a6d15859414d2be09cd448d4279af331c5d3e"
	QuicknetBeaconID  = "quicknet"

	TlockMethodQuicknet = "drand-quicknet"
)

Quicknet chain parameters (drand League of Entropy).

View Source
const GitHubPages = "https://eljojo.github.io/rememory"

GitHubPages is the GitHub Pages site URL.

View Source
const GitHubRepo = "https://github.com/eljojo/rememory"

GitHubRepo is the canonical repository URL.

View Source
const TlockContainerVersion = 1

TlockContainerVersion is the current tlock container format version.

Variables

View Source
var DrandEndpoints = []string{
	"https://api.drand.sh",
	"https://api2.drand.sh",
	"https://api3.drand.sh",
	"https://drand.cloudflare.com",
}

DrandEndpoints lists the public drand HTTP API relays, tried in order. api.drand.sh is first because drand.cloudflare.com returns improper CORS preflight responses (missing access-control-allow-methods), which causes fetch failures in Safari and Firefox.

View Source
var ErrEmptyPassphrase = errors.New("passphrase cannot be empty")

ErrEmptyPassphrase is returned when an empty passphrase is provided.

Functions

func BuildTlockContainer added in v0.0.16

func BuildTlockContainer(meta *TlockMeta, tlockCiphertext []byte) ([]byte, error)

BuildTlockContainer creates a ZIP containing tlock.json and manifest.tlock.age. The resulting ZIP is meant to be age-encrypted as the outer layer.

func Combine

func Combine(shares [][]byte) ([]byte, error)

Combine reconstructs the secret from k or more shares. Returns an error if fewer than 2 shares are provided. Note: If corrupted or wrong shares are provided, this may return garbage data without error. Use verification hashes to detect this.

func DecodeShareWords added in v0.0.8

func DecodeShareWords(words []string) (data []byte, index int, err error)

DecodeShareWords decodes 25 BIP39 words into share data and index. Auto-detects the word list language. The first 24 words are decoded to bytes; the 25th word carries index + checksum. Returns index=0 if the share index was > 15 (the sentinel value). Returns an error if the checksum doesn't match (wrong word order, typos, etc.).

func DecodeWords added in v0.0.8

func DecodeWords(words []string) ([]byte, error)

DecodeWords converts BIP39 English words back to bytes. Returns an error with typo suggestions if a word is not recognized.

func DecodeWordsLang added in v0.0.10

func DecodeWordsLang(words []string, lang Lang) ([]byte, error)

DecodeWordsLang converts BIP39 words back to bytes using the given language's list.

func Decrypt

func Decrypt(dst io.Writer, src io.Reader, passphrase string) error

Decrypt decrypts age-encrypted data using a passphrase.

func DecryptBytes

func DecryptBytes(encryptedData []byte, passphrase string) ([]byte, error)

DecryptBytes is a convenience function that decrypts data and returns bytes.

func EncodeWords added in v0.0.8

func EncodeWords(data []byte) []string

EncodeWords converts bytes to BIP39 English words (11 bits per word). 33 bytes (264 bits) produces exactly 24 words.

func EncodeWordsLang added in v0.0.10

func EncodeWordsLang(data []byte, lang Lang) []string

EncodeWordsLang converts bytes to BIP39 words in the given language (11 bits per word).

func Encrypt

func Encrypt(dst io.Writer, src io.Reader, passphrase string) error

Encrypt encrypts data using age with a passphrase (scrypt mode). The passphrase is used to derive an encryption key using scrypt.

func GetWordListSpecs added in v0.0.10

func GetWordListSpecs() []wordListSpec

GetWordListSpecs returns the spec metadata for all word lists (for testing).

func HashBytes

func HashBytes(b []byte) string

HashBytes returns the SHA-256 hash of bytes, prefixed with "sha256:".

func HashString

func HashString(s string) string

HashString returns the SHA-256 hash of a string, prefixed with "sha256:".

func IsTlockContainer added in v0.0.16

func IsTlockContainer(data []byte) bool

IsTlockContainer returns true if data looks like a tlock container ZIP. It checks for the ZIP magic bytes and the presence of a tlock.json entry.

func IsTlockTooEarly added in v0.0.16

func IsTlockTooEarly(err error) bool

IsTlockTooEarly returns true if the error wraps tlock.ErrTooEarly, meaning the drand round has not been reached yet.

func LookupWord added in v0.0.10

func LookupWord(lang Lang, word string) (int, bool)

LookupWord finds a word's BIP39 index in the given language. Tries exact match first, then NFD-stripped, then German digraph expansion. Returns (index, true) if found, (0, false) if not.

func NormalizeWord added in v0.0.10

func NormalizeWord(word string) string

NormalizeWord applies Unicode normalization for tolerant matching: lowercase, trim, NFD decompose, and strip combining marks. Examples: "Ábaco" → "abaco", "GÜNTHER" → "gunther", "čudež" → "cudez"

func ParseTimelockValue added in v0.0.16

func ParseTimelockValue(input string) (time.Time, error)

ParseTimelockValue parses a human-readable timelock duration or an absolute ISO 8601 datetime string, returning the target unlock time.

Supported formats:

  • "5min" — 5 minutes from now
  • "2h" — 2 hours from now
  • "30d" — 30 days from now
  • "2w" — 2 weeks from now
  • "6m" — 6 months from now
  • "1y" — 1 year from now
  • "2027-06-15T00:00:00Z" — absolute RFC 3339 datetime

func RecoverPassphrase added in v0.0.8

func RecoverPassphrase(recovered []byte, version int) string

RecoverPassphrase converts raw bytes from Combine() into the age passphrase. V1 shares contain the passphrase string directly; v2+ shares contain raw bytes that must be base64url-encoded.

func RoundForTime added in v0.0.16

func RoundForTime(target time.Time) uint64

RoundForTime returns the drand quicknet round number that will be emitted at or just after the given target time.

func SanitizeFilename

func SanitizeFilename(name string) string

SanitizeFilename converts a name to a filesystem-safe lowercase ASCII string. It transliterates accented/diacritic characters to their ASCII base form (e.g. "José" → "jose", "Müller" → "muller") using NFD decomposition.

func Split

func Split(secret []byte, n, k int) ([][]byte, error)

Split divides a secret into n shares, requiring k to reconstruct. Parameters:

  • secret: the data to split (e.g., a passphrase)
  • n: total number of shares to create (2-255)
  • k: minimum shares needed to reconstruct (2-n)

func SuggestWord added in v0.0.8

func SuggestWord(input string) string

SuggestWord finds the closest BIP39 English word by Levenshtein distance (max 2). Returns empty string if no close match is found.

func SuggestWordAllLangs added in v0.0.10

func SuggestWordAllLangs(input string) string

SuggestWordAllLangs searches all languages for the closest match (max distance 2).

func SuggestWordLang added in v0.0.10

func SuggestWordLang(input string, lang Lang) string

SuggestWordLang finds the closest word in a specific language's list (max distance 2).

func TimeForRound added in v0.0.16

func TimeForRound(round uint64) time.Time

TimeForRound returns the time at which a given drand quicknet round will be emitted.

func TlockDecrypt added in v0.0.16

func TlockDecrypt(dst io.Writer, src io.Reader) error

TlockDecrypt decrypts tlock-encrypted ciphertext by fetching the drand beacon signature for the round embedded in the ciphertext. Returns tlock.ErrTooEarly if the round has not been reached yet.

func TlockEncrypt added in v0.0.16

func TlockEncrypt(dst io.Writer, src io.Reader, roundNumber uint64) error

TlockEncrypt encrypts src to a specific drand round number using tlock. Encryption is offline — it uses only the embedded chain parameters (public key, scheme) and never contacts the drand network. The output is raw age binary (not armored).

func ValidateShamirParams

func ValidateShamirParams(n, k int) error

ValidateShamirParams validates the parameters for Shamir's Secret Sharing.

func VerifyHash

func VerifyHash(got, expected string) bool

VerifyHash checks if the given hash matches the expected value. Uses constant-time comparison to prevent timing attacks.

func WordListHash added in v0.0.10

func WordListHash(lang Lang) string

WordListHash computes the SHA-256 hash of a word list's canonical form (words joined by newline, with trailing newline).

Types

type ExtractedFile

type ExtractedFile struct {
	Name string
	Data []byte
}

ExtractedFile represents a file extracted from an archive.

func ExtractArchive added in v0.0.15

func ExtractArchive(data []byte) ([]ExtractedFile, error)

ExtractArchive detects the archive format and extracts accordingly. ZIP archives start with PK\x03\x04, gzip with \x1f\x8b.

func ExtractTarGz

func ExtractTarGz(tarGzData []byte) ([]ExtractedFile, error)

ExtractTarGz extracts files from tar.gz data in memory. This is used by both CLI and WASM for in-memory extraction. For file-based extraction, use the manifest package.

func ExtractTarGzReader

func ExtractTarGzReader(r io.Reader) ([]ExtractedFile, error)

ExtractTarGzReader extracts files from a tar.gz reader.

func ExtractZip added in v0.0.15

func ExtractZip(zipData []byte) ([]ExtractedFile, error)

ExtractZip extracts files from ZIP data in memory. Same security checks (path traversal, size limits) as ExtractTarGz.

type Lang added in v0.0.10

type Lang string

Lang identifies a supported BIP39 word list language.

const (
	LangEN    Lang = "en"
	LangES    Lang = "es"
	LangFR    Lang = "fr"
	LangDE    Lang = "de"
	LangSL    Lang = "sl"
	LangPT    Lang = "pt"
	LangZH_TW Lang = "zh-TW"
)

func AllLangs added in v0.0.10

func AllLangs() []Lang

AllLangs returns all supported word list languages.

func DecodeShareWordsAuto added in v0.0.10

func DecodeShareWordsAuto(words []string) (data []byte, index int, lang Lang, err error)

DecodeShareWordsAuto decodes 25 BIP39 words with auto-detected language. Returns the decoded data, share index, detected language, and any error.

func DetectWordListLang added in v0.0.10

func DetectWordListLang(words []string) Lang

DetectWordListLang identifies which language a set of words belongs to. Returns the language where the most words match. Requires >50% match. Returns empty string if no language matches.

type Share

type Share struct {
	Version   int       // Format version (1 or 2)
	Index     int       // Which share (1-indexed for humans)
	Total     int       // Total shares (N)
	Threshold int       // Required shares (K)
	Holder    string    // Name of the person holding this share
	Created   time.Time // When the share was created
	Data      []byte    // The actual share bytes
	Checksum  string    // SHA-256 of Data
}

Share represents a single Shamir share with metadata.

func NewShare

func NewShare(version, index, total, threshold int, holder string, data []byte) *Share

NewShare creates a Share with the given parameters and computes its checksum.

func ParseCompact added in v0.0.8

func ParseCompact(s string) (*Share, error)

ParseCompact parses a compact-encoded share string back into a Share. It validates the format, decodes the data, and verifies the short checksum.

func ParseShare

func ParseShare(content []byte) (*Share, error)

ParseShare parses a share from its encoded format. The content can be a full README.txt file - it will find the share block.

func (*Share) CompactEncode added in v0.0.8

func (s *Share) CompactEncode() string

CompactEncode returns a short string encoding of the share suitable for QR codes and URL fragments. Format: RM{version}:{index}:{total}:{threshold}:{base64url_data}:{short_check} The short_check is the first 4 hex characters of the SHA-256 of the raw share data.

func (*Share) Encode

func (s *Share) Encode() string

Encode converts the share to a human-readable PEM-like format.

func (*Share) Filename

func (s *Share) Filename() string

Filename returns a suggested filename for this share.

func (*Share) Verify

func (s *Share) Verify() error

Verify checks that the share's checksum matches its data. Uses constant-time comparison to prevent timing attacks.

func (*Share) Words added in v0.0.8

func (s *Share) Words() ([]string, error)

Words returns this share's data encoded as 25 BIP39 English words. The first 24 words encode the share data (33 bytes = 264 bits, 11 bits per word). The 25th word packs 4 bits of share index + 7 bits of checksum (see word25 layout above). Returns an error for v1 shares or if the share index is negative.

func (*Share) WordsForLang added in v0.0.10

func (s *Share) WordsForLang(lang Lang) ([]string, error)

WordsForLang returns this share's data encoded as 25 BIP39 words in the given language.

type TlockMeta added in v0.0.16

type TlockMeta struct {
	V      int    `json:"v"`
	Method string `json:"method"`
	Round  uint64 `json:"round"`
	Unlock string `json:"unlock"` // RFC 3339 timestamp
	Chain  string `json:"chain"`
}

TlockMeta holds the tlock-specific metadata stored inside the container.

func OpenTlockContainer added in v0.0.16

func OpenTlockContainer(data []byte) (*TlockMeta, []byte, error)

OpenTlockContainer reads a tlock container ZIP and returns the metadata and the tlock-encrypted ciphertext.

func (*TlockMeta) UnlockTime added in v0.0.16

func (t *TlockMeta) UnlockTime() (time.Time, error)

UnlockTime parses the Unlock field as a time.Time.

type WordListInfo added in v0.0.10

type WordListInfo struct {
	Lang         Lang
	SourceURL    string
	ExpectedHash string // SHA-256 of the .txt file contents
	Words        [2048]string
}

WordListInfo describes a BIP39 word list: its source, expected hash, and words.

func GetWordList added in v0.0.10

func GetWordList(lang Lang) *WordListInfo

GetWordList returns the word list for the given language. Returns nil if the language is not supported.

Jump to

Keyboard shortcuts

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