HPPR-009 ยท HSB3 Signatures

HSB3 is a BIP-340 style Schnorr signature over secp256k1.

HSB3 uses BLAKE3-256 for all hashing and key derivation tags. Reference code lives in rust/libs/hsb3.

Parameters

Helper notation:

Key Generation

  1. Draw random 32-byte d0; reject 0 and d0 >= n.
  2. Set d = d0, compute P = d*G.
  3. If P.y is odd, set d = n - d and recompute P.
  4. Private key is d; public key is bytes(P.x).

The even-y convention is mandatory.

Deterministic Key Derivation

Derive a keypair from arbitrary secret bytes.

  1. Initialize BLAKE3 derive mode with tag hppr-๐Ÿ–ง/adhoc-key.
  2. Feed secret bytes.
  3. Enter XOF mode.
  4. Rejection sample 32-byte candidates until 0 < d0 < n.
  5. Apply the same even-y normalization as key generation.

Conformance:

Ring1 Adhoc Derivation (Argon2id)

Ring1 secret tokens derive through Argon2id first.

Token format:

V.<b64a>.H3

Argon2id inputs:

If HELLO omits PHC, defaults are m=12288, t=3, p=1.

Then derive HSB3 key from:

<derived-token>/<ring1>/<repo-vkey>

Signing

Inputs:

Rules:

Algorithm:

  1. t = tagged(aux, auxRand32)
  2. mask = t xor bytes(d)
  3. k0 = tagged(nonce, mask || Px || msg32) mod n; reject k0 = 0
  4. R = k0*G; if R.y odd then k = n-k0, else k = k0
  5. e = tagged(challenge, bytes(R.x) || Px || msg32) mod n
  6. s = (k + e*d) mod n
  7. signature bytes are bytes(R.x) || bytes(s)

Text form uses B64A.

Verification

Inputs: signature r||s, public key Px, and msg32.

  1. Parse r, s; reject r >= p or s >= n.
  2. Recover P from Px and take even-y root.
  3. e = tagged(challenge, bytes(r) || Px || msg32) mod n
  4. R' = s*G - e*P; reject infinity or odd y.
  5. Accept iff R'.x == r.

Conformance

Implementations: