masterseed

package module
v1.0.2 Latest Latest
Warning

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

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

README

MasterSeed

MasterSeed 是 Keymaster Seed V1 的 Go 与 TypeScript SDK 项目。

源文件固定按 256 KiB(262144 字节)分块。每个数据块计算 SHA-256,所得 32 字节原始二进制摘要按块顺序直接拼接,形成种子文件:

seed_bytes = block_hash[0] || ... || block_hash[n-1]
seed_hash  = SHA256(seed_bytes)

种子文件不保存十六进制文本。Hex 仅用于 API、日志和传播时表示 seed_hash

项目文档

  • 需求文档:产品范围、功能需求和验收标准
  • 设计文档:V1 二进制格式、算法、SDK API 与错误模型
  • 施工单:Go、TypeScript、共享测试和发布任务
  • API 摘要:两个 SDK 的公开操作、类型和错误判断方式

实现包含:

  • 根目录 Go module:包名 masterseed
  • typescript/:运行时无关的核心 package;
  • masterseed/node:Node.js 文件路径适配层;
  • spec/seed-v1.mdtestdata/v1/vectors.json:公开格式和跨语言黄金向量。

Go 最小示例

种子文件保存的是原始二进制摘要;下面的 SeedHashHex 仅用于展示和传播。

package main

import (
    "context"
    "fmt"
    "github.com/bsv8/MasterSeed"
)

func main() {
    info, err := masterseed.CreateSeedFile(
        context.Background(), "source.bin", "source.seed",
        masterseed.CreateSeedFileOptions{},
    )
    if err != nil { panic(err) }
    fmt.Println(info.SeedHashHex)
}

完整源文件验证先取得可信的 seed_hash,再调用 VerifySourceFile

expected, err := masterseed.ParseDigestHex(seedHashHex)
if err != nil { panic(err) }
_, err = masterseed.VerifySourceFile(context.Background(), "source.bin", "source.seed", expected)

TypeScript 最小示例

核心 API 接收任意 Uint8Array 异步 chunk;计数、大小和偏移使用 bigint

import { createSeed, Digest } from "masterseed";
import { createSeedFile, verifySourceFile } from "masterseed/node";

const info = await createSeed(
  (async function* () { yield new TextEncoder().encode("abc"); })(),
  { async write(bytes) { /* persist all 32 raw bytes */ } }
);
console.log(info.seedHashHex);

await createSeedFile("source.bin", "source.seed");
await verifySourceFile("source.bin", "source.seed", Digest.fromHex(info.seedHashHex));

默认路径生成禁止覆盖已有目标,并在同目录临时文件完成后才发布。失败或取消会清理临时文件。

检查命令

go test ./...
go vet ./...
cd typescript && npm ci && npm run check

V1 的 BLOCK_SIZE、SHA-256 和原始 32 字节摘要布局是协议常量;需要头部、元数据、其他块大小或其他算法时必须定义新版本,不能修改 V1 文件字节。

Documentation

Index

Constants

View Source
const (
	Format        = "keymaster-seed-v1"
	BlockSize     = 256 * 1024
	DigestSize    = 32
	HashAlgorithm = "SHA-256"
	// Upper-case aliases mirror the protocol notation used in the public spec.
	FORMAT         = Format
	BLOCK_SIZE     = BlockSize
	DIGEST_SIZE    = DigestSize
	HASH_ALGORITHM = HashAlgorithm
)

V1 constants are part of the wire format and must not change within V1.

Variables

This section is empty.

Functions

func BlockCountForSourceSize

func BlockCountForSourceSize(sourceSize uint64) uint64

BlockCountForSourceSize applies the V1 empty-file and aligned-file rules.

func IsCode

func IsCode(err error, code ErrorCode) bool

IsCode reports whether err or one of its causes has code.

func SeedOffset

func SeedOffset(blockIndex uint64) (uint64, error)

SeedOffset returns blockIndex*DIGEST_SIZE after checking overflow.

func SeedSizeForBlockCount

func SeedSizeForBlockCount(blockCount uint64) (uint64, error)

SeedSizeForBlockCount checks the block-count multiplication used by callers that work with untrusted metadata.

func SourceOffset

func SourceOffset(blockIndex uint64) (uint64, error)

SourceOffset returns blockIndex*BLOCK_SIZE after checking overflow.

Types

type CreateSeedFileOptions

type CreateSeedFileOptions struct {
	Overwrite bool
	Sync      bool
}

CreateSeedFileOptions controls atomic path publishing.

type Digest

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

Digest is an immutable, fixed-size SHA-256 digest value.

func DigestFromBytes

func DigestFromBytes(value []byte) (Digest, error)

DigestFromBytes constructs a Digest only from exactly 32 bytes.

func DigestFromHex

func DigestFromHex(value string) (Digest, error)

DigestFromHex is an alias for ParseDigestHex.

func HashSeed

func HashSeed(ctx context.Context, seed io.Reader) (Digest, error)

HashSeed computes SHA-256 over any seed bytes without validating its length.

func NewDigest

func NewDigest(value []byte) (Digest, error)

NewDigest is an alias for DigestFromBytes for callers that prefer a constructor-style name.

func ParseDigestHex

func ParseDigestHex(value string) (Digest, error)

ParseDigestHex parses exactly 64 hexadecimal characters. Whitespace and 0x prefixes are intentionally not accepted.

func ReadBlockHash

func ReadBlockHash(ctx context.Context, seed io.ReaderAt, seedSize, blockIndex uint64) (Digest, error)

ReadBlockHash reads one raw digest from a random-access seed file.

func Sum256

func Sum256(value []byte) Digest

Sum256 returns the digest of value.

func VerifyBlock

func VerifyBlock(ctx context.Context, block []byte, expected Digest) (Digest, error)

VerifyBlock hashes one caller-provided block. A short block is accepted; an API caller needs source-length context to decide whether it is the last one.

func (Digest) Bytes

func (d Digest) Bytes() []byte

Bytes returns a copy of the raw 32-byte digest.

func (Digest) Equal

func (d Digest) Equal(other Digest) bool

Equal compares two digest values.

func (Digest) Hex

func (d Digest) Hex() string

Hex returns the canonical lower-case hexadecimal representation.

func (Digest) String

func (d Digest) String() string

String implements fmt.Stringer using the canonical hexadecimal form.

type Error

type Error struct {
	Code         ErrorCode
	Message      string
	Cause        error
	Operation    string
	Path         string
	BlockIndex   *uint64
	BlockCount   *uint64
	SourceOffset *uint64
	SeedSize     *uint64
	Expected     *Digest
	Actual       *Digest
}

Error is the structured error returned by the SDK. Context fields are optional and are populated only when relevant to the failure.

func (*Error) Error

func (e *Error) Error() string

func (*Error) Unwrap

func (e *Error) Unwrap() error

type ErrorCode

type ErrorCode string

ErrorCode is stable across the Go and TypeScript SDKs.

const (
	InvalidSeedLength    ErrorCode = "INVALID_SEED_LENGTH"
	InvalidHashEncoding  ErrorCode = "INVALID_HASH_ENCODING"
	SeedHashMismatch     ErrorCode = "SEED_HASH_MISMATCH"
	BlockHashMismatch    ErrorCode = "BLOCK_HASH_MISMATCH"
	SourceTooShort       ErrorCode = "SOURCE_TOO_SHORT"
	SourceTooLong        ErrorCode = "SOURCE_TOO_LONG"
	BlockIndexOutOfRange ErrorCode = "BLOCK_INDEX_OUT_OF_RANGE"
	IntegerOverflow      ErrorCode = "INTEGER_OVERFLOW"
	TargetExists         ErrorCode = "TARGET_EXISTS"
	ReadFailed           ErrorCode = "READ_FAILED"
	WriteFailed          ErrorCode = "WRITE_FAILED"
	Aborted              ErrorCode = "ABORTED"
	InvalidArgument      ErrorCode = "INVALID_ARGUMENT"
)

func CodeOf

func CodeOf(err error) ErrorCode

CodeOf extracts a stable SDK error code through wrapped errors.

type SeedInfo

type SeedInfo struct {
	Format          string
	BlockSize       uint64
	BlockCount      uint64
	SourceSize      uint64
	SourceSizeKnown bool
	SeedSize        uint64
	SeedHash        Digest
	SeedHashHex     string
}

SeedInfo describes a seed file. SourceSizeKnown is false for HashSeed and InspectSeed because a seed file does not encode source length.

func CreateSeed

func CreateSeed(ctx context.Context, source io.Reader, sink io.Writer) (SeedInfo, error)

CreateSeed hashes source in protocol-sized blocks and writes raw 32-byte digests to sink. It never writes hexadecimal text to the sink.

func CreateSeedFile

func CreateSeedFile(ctx context.Context, sourcePath, seedPath string, options CreateSeedFileOptions) (info SeedInfo, err error)

CreateSeedFile writes a seed beside the target, then publishes it. The default is no-overwrite; an incomplete seed is never left at seedPath.

func InspectSeed

func InspectSeed(ctx context.Context, seed io.Reader) (SeedInfo, error)

InspectSeed computes seed_hash and requires the seed length to be a multiple of the raw digest size.

func VerifySeed

func VerifySeed(ctx context.Context, seed io.Reader, expected Digest) (SeedInfo, error)

VerifySeed strictly inspects a seed and compares its raw-byte hash with the caller's expected digest using a constant-time comparison.

type VerifyInfo

type VerifyInfo struct {
	SeedInfo
	BlocksVerified uint64
}

VerifyInfo describes a successful complete source verification.

func VerifySource

func VerifySource(ctx context.Context, source io.Reader, seed io.Reader) (VerifyInfo, error)

VerifySource validates every source block against the raw digests in seed, then checks that neither stream contains extra data.

func VerifySourceFile

func VerifySourceFile(ctx context.Context, sourcePath, seedPath string, expected Digest) (VerifyInfo, error)

VerifySourceFile verifies the seed hash before reopening the seed for the complete source pass, so untrusted seed contents are not used unchecked.

Jump to

Keyboard shortcuts

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