pomfrit

package
v0.1.66 Latest Latest
Warning

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

Go to latest
Published: Jul 24, 2026 License: Apache-2.0 Imports: 5 Imported by: 0

Documentation

Overview

Package pomfrit implements the PoMFRIT One-More-MAYO blind signature (Baum, Beckmann, Beullens, Mukherjee, Rechberger — "Concretely Efficient Blind Signatures Based on VOLE-in-the-Head Proofs and the MAYO Trapdoor") in pure, cgo-free Go targeting the TamaGo bare-metal runtime.

It is a faithful transpile of the pq_blind_signatures reference: the vole/optimized_bs C++ VOLE-in-the-Head engine (GGM-forest BAVC, small-VOLE, vole_check universal hashing, degree-2 QuickSilver, the MAYO-eval circuit, and the vole_prove/vole_verify Fiat-Shamir flow) glued to MAYO-C's salt-free preimage sampler (mayo.SignWithoutHashing in the sibling mayo package). Every layer is validated byte-for-byte against dumpers compiled from those reference sources; the AES-CTR PRG and the ZK Horner hash are reused from the sibling faest package.

See SOURCES.md and PLAN.md for per-construct provenance and the verification ledger.

Status

Experimental and unaudited. Correctness rests on reference KATs, not a security review.

Public entry points

MayoOWFL1, MayoOWFL3, MayoOWFL5  // MayoOWF, the three v1 MAYO instances
(MayoOWF).Sign1                  // user: blind the message, t = h + r
mayo.SignWithoutHashing          // signer: MAYO preimage of t (sign_2)
(MayoOWF).Sign3                  // user: VOLE-in-the-Head proof
(MayoOWF).BlindVerify            // verifier: recompute h, run vole_verify
(MayoOWF).Prove / Verify         // the underlying VOLE proof pair
Example

The full One-More-MAYO blind signature at L1, playing all three roles: the user blinds the message (sign_1), the signer computes a MAYO preimage of the blinded message (sign_2), the user turns it into a VOLE-in-the-Head proof (sign_3), and the verifier checks the proof without ever seeing the signer's key or the blinding.

package main

import (
	"fmt"

	"github.com/maceip/tamayo/mayo"
	"github.com/maceip/tamayo/pomfrit"
)

func main() {
	o := pomfrit.MayoOWFL1
	mp := &mayo.Mayo1

	// Signer key material: compact keypair; verifiers use the expanded key.
	seed := make([]byte, mp.SKSeedBytes)
	cpk, csk, err := mp.CompactKeyGen(seed)
	if err != nil {
		panic(err)
	}
	epk, err := mp.ExpandPK(cpk)
	if err != nil {
		panic(err)
	}

	msg := []byte("This is a message.")
	rAdditional := make([]byte, 32) // session randomness bound into Fiat-Shamir

	// sign_1 (user): blind the message, t = h + r.
	t, st, h := o.Sign1(msg, rAdditional)

	// sign_2 (signer): MAYO preimage of the blinded message.
	bsig := mp.SignWithoutHashing(t, csk)

	// sign_3 (user): prove knowledge of a valid preimage without revealing it.
	proof := o.Sign3(epk, h, bsig, st, rAdditional)

	// verify: recompute h and run vole_verify.
	fmt.Println("blind signature valid:", o.BlindVerify(epk, msg, proof.Bytes, rAdditional))

	tampered := append([]byte(nil), proof.Bytes...)
	tampered[0] ^= 1
	fmt.Println("tampered rejected:", !o.BlindVerify(epk, msg, tampered, rAdditional))
}
Output:
blind signature valid: true
tampered rejected: true

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	MayoForestL1 = NewMayoForest(9, 16, 3752)
	MayoForestL3 = NewMayoForest(14, 24, 5624)
	MayoForestL5 = NewMayoForest(19, 32, 7960)
)

The three v1 MAYO small parameter sets (mayo_{128,192,256}_s). WitnessBits from VOLEMAYO_WITNESS_SIZE_BITS: L1 4*78+4*10*86, L3 4*108+4*11*118, L5 4*142+4*12*154.

View Source
var (
	VoleMayoL1 = MayoParams{N: 86, M: 78, O: 8, V: 78, K: 10, FTail: [4]byte{8, 1, 1, 0}}
	VoleMayoL3 = MayoParams{N: 118, M: 108, O: 10, V: 108, K: 11, FTail: [4]byte{8, 0, 1, 7}}
	VoleMayoL5 = MayoParams{N: 154, M: 142, O: 12, V: 142, K: 12, FTail: [4]byte{4, 0, 8, 1}}
)

The three v1 MAYO instances (L1/L3/L5). F_TAIL from VOLEMAYO_F_TAIL_{78,108,142}.

The three v1 MAYO small instances.

Functions

This section is empty.

Types

type MayoForest

type MayoForest struct {
	Tau         int
	LambdaBytes int
	WitnessBits int
	// contains filtered or unexported fields
}

MayoForest is one v1 MAYO ggm_forest parameter set. minK/maxK and the tree counts are pure functions of (Tau, lambda) exactly as in VECTOR_COMMITMENT_CONSTANTS<TAU, DELTA_BITS=lambda>. WitnessBits = VOLEMAYO_WITNESS_SIZE_BITS (= 4*M + 4*K*N) fixes the VOLE row count.

func NewMayoForest

func NewMayoForest(tau, lambdaBytes, witnessBits int) MayoForest

NewMayoForest builds the parameter set for the given tau, lambda (bytes) and witness-bit count.

func (MayoForest) MayoForestCommit

func (m MayoForest) MayoForestCommit(seed, iv []byte) (voleKeys [][][]byte, hashedLeaves [][]byte, check []byte, forest [][][][]byte)

MayoForestCommit expands all TAU trees from the seed and returns the per-tree natural-order small-VOLE leaf keys (first lambda bytes of each leaf's shake hash), the per-tree concatenated leaf hashes (the next 2*lambda), and the hash-of-hashes check (2*lambda). Transpiled from ggm_forest_bavc::commit + hash_hashed_leaves.

func (MayoForest) MayoForestOpen

func (m MayoForest) MayoForestOpen(forest [][][][]byte, hashedLeaves [][]byte, deltaBytes []byte) []byte

MayoForestOpen produces the all-but-Delta opening: for each tree, walk from the root along the Delta-selected path (LSB-first per level, delta byte 0/0xff) emitting the sibling node key at each level, then the hidden leaf's 2*lambda hash. Transpiled from ggm_forest_bavc::open. deltaBytes is the per-tree little-endian expanded Delta (delta_bits bytes total).

func (MayoForest) MayoForestVerify

func (m MayoForest) MayoForestVerify(iv, opening, deltaBytes []byte) (voleKeys [][][]byte, check []byte, leafIdx []int)

MayoForestVerify reconstructs, per tree, all leaf VOLE keys except the hidden one (from the opening's co-path siblings) plus every leaf hash (the hidden leaf's hash comes from the opening tail), and recomputes the hash-of-hashes check. Transpiled from ggm_forest_bavc::verify. deltaBytes is the expanded per-tree Delta (lambda bytes). Returns per-tree natural-order vole keys (the hidden slot is a zero dummy), the hash-of-hashes check, and the per-tree hidden leaf indices.

func (MayoForest) MayoVoleCommit

func (m MayoForest) MayoVoleCommit(seed, iv []byte) MayoVoleCommitResult

MayoVoleCommit runs the full sender vole_commit and keeps the BAVC forest and leaf hashes for a subsequent Open. Transpiled from vole_commit.inc vole_commit.

func (MayoForest) TransposeToMacs

func (m MayoForest) TransposeToMacs(v []byte, rows int) [][]byte

TransposeToMacs converts the column-major VOLE matrix (lambda columns, each colLen 16-byte blocks) into row-major field elements: macs[row] is the lambda-bit value whose bit c is column c's bit `row`. Matches transpose_secpar truncated to the given number of rows. Returns rows field elements as bytes.

func (MayoForest) VoleCheckSender

func (m MayoForest) VoleCheckSender(u, v, challenge []byte) (proof, transcriptHash []byte)

VoleCheckSender is VoleCheckSenderBlocks plus the fresh-hasher finalization (u_tilde ++ v-col hashes -> 2*lambda), used by the isolated vole_check KAT.

func (MayoForest) VoleCheckSenderBlocks

func (m MayoForest) VoleCheckSenderBlocks(u, v, challenge []byte) (proof []byte, colHashes [][]byte)

VoleCheckSenderBlocks runs the sender vole_check over (u, v) and returns the ordered blocks it absorbs into the transcript hasher: the u_tilde proof (HASH_BYTES = lambda+2) followed by the lambda v-column hashes. Transpiled from vole_check_both (verifier=false): col=-1 (u) yields u_tilde and is absorbed first, then each v column.

func (MayoForest) VoleCommitSender

func (m MayoForest) VoleCommitSender(seed, iv []byte) (u, v, commitment, check []byte)

VoleCommitSender runs vole_commit's sender path: BAVC-commit the seed, then small-VOLE each tree, gluing the columns into the full v matrix and emitting tree 0's accum as u and the later trees' corrections into commitment. Returns u (COL_LEN blocks), v (lambda columns * COL_LEN blocks), the corrections commitment (VOLE_ROWS/8 bytes per tree>0) and the BAVC check.

func (MayoForest) VoleReconstruct

func (m MayoForest) VoleReconstruct(iv, opening, commitment, deltaBytes []byte) (q, check []byte)

VoleReconstruct rebuilds the verifier VOLE tags q (lambda columns, column- major) from the opening and the BAVC corrections. Transpiled from vole_reconstruct. Returns q and the recomputed vole_commit check.

type MayoOWF

type MayoOWF struct {
	F MayoForest
	P MayoParams
}

MayoOWF binds the ggm_forest/VOLE parameters (MayoForest) with the whipped MAYO map parameters (MayoParams) for one security level.

func (MayoOWF) BlindVerify

func (o MayoOWF) BlindVerify(epk, m, proof, rAdditional []byte) bool

BlindVerify is the blind-signature verify: recompute h = SHAKE256(m || proof1) from the proof and check the VOLE proof against epk || h. Malformed proofs and wrong-sized keys are rejected, not panicked on.

func (MayoOWF) ProofSize

func (o MayoOWF) ProofSize() int

ProofSize returns the exact byte length of a proof for this instance (6895/15862/29615 for L1/L3/L5).

func (MayoOWF) Prove

func (o MayoOWF) Prove(sk, pk, rAdditional []byte) MayoProof

Prove runs vole_prove_1 + vole_prove_2 in one shot (used by the VOLE-only KAT). sk is the packed secret key (public || witness), pk the packed public key (expanded_pk || h).

func (MayoOWF) Prove1

func (o MayoOWF) Prove1(rAdditional []byte) MayoProveState

Prove1 runs vole_prove_1: derive the VOLE seed/iv deterministically from SHAKE(0x03)/H4, commit the ggm_forest VOLE, and derive r and chal1.

func (MayoOWF) Prove2

func (o MayoOWF) Prove2(st MayoProveState, packedPk, packedSk, rAdditional []byte) MayoProof

Prove2 runs vole_prove_2 from a prove-1 state, the packed pk (expanded_pk || h) and packed sk (packed_pk || r || witness_s), returning the full proof.

func (MayoOWF) Sign1

func (o MayoOWF) Sign1(m, rAdditional []byte) (t []byte, st MayoProveState, h []byte)

Sign1 is the blind-signature sign_1: run prove_1, form the blinded message t = h + r with h = SHAKE256(m || proof1), and return t, the carried state, and h. h uses SHAKE256 at every level (reference mayo-c-sys shake256).

func (MayoOWF) Sign3

func (o MayoOWF) Sign3(epk, h, bsig []byte, st MayoProveState, rAdditional []byte) MayoProof

Sign3 is the blind-signature sign_3: assemble packed_pk = epk || h and packed_sk = packed_pk || r || bsig, then run prove_2. bsig is the MAYO preimage of t from sign_2 (mayo.SignWithoutHashing).

func (MayoOWF) Verify

func (o MayoOWF) Verify(pk, rAdditional, proof []byte) bool

Verify checks a One-More-MAYO VOLE proof against (pk, r_additional). Transpiled from vole_verify. Returns true iff the proof's Delta equals the recomputed H_2^3(chall2 || qs_check || qs_proof).

type MayoParams

type MayoParams struct {
	N, M, O, V, K int
	FTail         [4]byte
}

MayoParams is the whipped MAYO instance proven by One-More-MAYO. Values from pq_blind_signatures vole/optimized_bs/parameters.hpp (VOLEMAYO_*): N, M, O, V=N-O, K, and the whipping tail polynomial F_TAIL.

func (MayoParams) MayoConstraintProve

func (p MayoParams) MayoConstraintProve(qs *QS2Prover, pkBytes, h, chal2 []byte)

MayoConstraintProve builds the prover's degree-2 constraint element u + t_embedded and folds it into the QuickSilver via AddConstraint. Transpiled from enc_constraints (prover instantiation).

func (MayoParams) MayoConstraintVerify

func (p MayoParams) MayoConstraintVerify(qs *QS2Verifier, pkBytes, h, chal2 []byte)

MayoConstraintVerify builds the verifier's evaluation of u + t_embedded and folds it into the QuickSilver. Transpiled from enc_constraints (verifier).

type MayoProof

type MayoProof struct {
	Bytes      []byte
	Commitment []byte
	UTilde     []byte
	D          []byte
	QSProof    []byte
	Opening    []byte
	Delta      []byte
	IVPre      []byte
}

MayoProof holds the assembled One-More-MAYO VOLE proof and its ordered segments, matching the reference proof byte layout.

type MayoProveState

type MayoProveState struct {
	VC    MayoVoleCommitResult
	IVPre []byte
	Chal1 []byte
	R     []byte
}

MayoProveState is the vole_prove_1 output carried into vole_prove_2 (the VOLEMAYOProofState of the reference): the VOLE correlation, BAVC artifacts, the derived r (= u[:R_BYTES]), the commitment (proof1) and chal1.

type MayoVoleCommitResult

type MayoVoleCommitResult struct {
	U, V, Commitment, Check []byte
	Forest                  [][][][]byte
	HashedLeaves            [][]byte
}

MayoVoleCommitResult bundles the sender vole_commit outputs plus the BAVC artifacts (forest, hashed leaves) needed to open at Delta later.

type QS2Prover

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

QS2Prover mirrors quicksilver_state<S, false, 2>. macs holds one field element per witness bit, including the lambda MAC-mask bits appended after the real witness; witness likewise carries lambda/8 extra mask bytes.

func NewQS2Prover

func NewQS2Prover(f field.Big, witness []byte, macs [][]uint64, challenge []byte) *QS2Prover

NewQS2Prover initializes the prover state from the 3*lambda+64-bit QuickSilver challenge, one ZKHasher per MAC-polynomial coefficient.

func (*QS2Prover) AddConstraint

func (p *QS2Prover) AddConstraint(x QSP2El)

AddConstraint mirrors add_constraint: x is lifted to degree 2, its committed value must be zero, and MAC coefficient i feeds hasher i.

func (*QS2Prover) ConstEl

func (p *QS2Prover) ConstEl(c []uint64) QSP2El

ConstEl returns the degree-0 public constant c.

func (*QS2Prover) Field

func (p *QS2Prover) Field() field.Big

field on QS2Prover/Verifier exposes the working field for callers.

func (*QS2Prover) GetWitnessBit

func (p *QS2Prover) GetWitnessBit(index int) QSP2Bit

GetWitnessBit mirrors get_witness_bit: degree-1 gf2 with the bit's MAC as the constant coefficient.

func (*QS2Prover) LoadWitness4BitsAndCombine

func (p *QS2Prover) LoadWitness4BitsAndCombine(bitIndex int) QSP2El

LoadWitness4BitsAndCombine mirrors load_witness_4_bits_and_combine.

func (*QS2Prover) LoadWitness8BitsAndCombine

func (p *QS2Prover) LoadWitness8BitsAndCombine(bitIndex int) QSP2El

LoadWitness8BitsAndCombine mirrors load_witness_8_bits_and_combine.

func (*QS2Prover) Prove

func (p *QS2Prover) Prove(witnessBits int) (proof, check []byte)

Prove mirrors prove(witness_bits, proof, check). The MAC mask (combine_mac_masks over the lambda mask bits) enters the coefficient-0 hash and the mask witness bits, read as a field element, the coefficient-1 hash.

func (*QS2Prover) ZeroEl

func (p *QS2Prover) ZeroEl(d int) QSP2El

ZeroEl returns the zero element of degree d.

type QS2Verifier

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

QS2Verifier mirrors quicksilver_state<S, true, 2>. macs holds the verifier keys (tag + bit*Delta) for every witness bit including the mask bits.

func NewQS2Verifier

func NewQS2Verifier(f field.Big, macs [][]uint64, delta []uint64, challenge []byte) *QS2Verifier

NewQS2Verifier initializes the verifier state; deltaPowers = [Delta, Delta^2] as in the reference constructor.

func (*QS2Verifier) AddConstraint

func (v *QS2Verifier) AddConstraint(x QSV2El)

AddConstraint mirrors add_constraint (verifier): lift to degree 2 and hash the evaluation.

func (*QS2Verifier) ConstEl

func (v *QS2Verifier) ConstEl(c []uint64) QSV2El

ConstEl returns the degree-0 public constant c.

func (*QS2Verifier) Field

func (v *QS2Verifier) Field() field.Big

func (*QS2Verifier) GetWitnessBit

func (v *QS2Verifier) GetWitnessBit(index int) QSV2El

GetWitnessBit mirrors get_witness_bit (verifier): degree 1, the key.

func (*QS2Verifier) LoadWitness4BitsAndCombine

func (v *QS2Verifier) LoadWitness4BitsAndCombine(bitIndex int) QSV2El

LoadWitness4BitsAndCombine mirrors the verifier combine_4_bits path.

func (*QS2Verifier) LoadWitness8BitsAndCombine

func (v *QS2Verifier) LoadWitness8BitsAndCombine(bitIndex int) QSV2El

LoadWitness8BitsAndCombine mirrors the verifier combine_8_bits path.

func (*QS2Verifier) Verify

func (v *QS2Verifier) Verify(witnessBits int, proof []byte) (check []byte)

Verify mirrors verify(witness_bits, proof, check): the key mask plus proof * Delta^(max_deg-1) closes the hash.

func (*QS2Verifier) ZeroEl

func (v *QS2Verifier) ZeroEl(d int) QSV2El

ZeroEl returns the zero element of degree d.

type QSP2Bit

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

QSP2Bit mirrors quicksilver_gf2<prover, deg>: deg ascending MAC coefficients plus the committed bit.

func (QSP2Bit) Deg

func (a QSP2Bit) Deg() int

Deg returns the polynomial degree.

func (QSP2Bit) Value

func (a QSP2Bit) Value() byte

Value returns the committed bit.

type QSP2El

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

QSP2El mirrors quicksilver_gfsecpar<prover, deg>: deg+1 ascending MAC coefficients, mac[deg] being the committed value.

func (QSP2El) Add

func (a QSP2El) Add(b QSP2El) QSP2El

Add returns a + b, lifting the lower-degree operand as the reference's implicit conversion constructors do.

func (QSP2El) AddOne

func (a QSP2El) AddOne() QSP2El

AddOne returns a + 1 (operator+(a, poly1)): the constant is a same-degree gfsecpar whose only nonzero coefficient is the leading one.

func (QSP2El) Deg

func (a QSP2El) Deg() int

Deg returns the polynomial degree.

func (QSP2El) Mul

func (a QSP2El) Mul(b QSP2El) QSP2El

Mul returns a * b; degrees add. Coefficient k of the product MAC polynomial is Sum_{i+j=k} a[i]*b[j] (poly2d operator* followed by reduce_to).

func (QSP2El) MulScalar

func (a QSP2El) MulScalar(c []uint64) QSP2El

MulScalar returns c * a for a public field element c (quicksilver_gfsecpar<0>(c) * a): every coefficient is scaled.

func (QSP2El) Value

func (a QSP2El) Value() []uint64

Value returns the committed field element (the leading MAC coefficient).

type QSV2El

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

QSV2El mirrors both verifier value types (gf2 derives from gfsecpar in the reference): the MAC polynomial evaluated at Delta, plus the degree.

func (QSV2El) Add

func (a QSV2El) Add(b QSV2El) QSV2El

Add returns a + b, lifting the lower-degree operand.

func (QSV2El) AddOne

func (a QSV2El) AddOne() QSV2El

AddOne returns a + 1: the same-degree constant 1 evaluates to Delta^deg.

func (QSV2El) Deg

func (a QSV2El) Deg() int

Deg returns the polynomial degree.

func (QSV2El) Mul

func (a QSV2El) Mul(b QSV2El) QSV2El

Mul returns a * b; evaluations multiply and degrees add.

func (QSV2El) MulScalar

func (a QSV2El) MulScalar(c []uint64) QSV2El

MulScalar returns c * a for a public field element c (degree preserved).

Jump to

Keyboard shortcuts

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