Documentation
¶
Overview ¶
Package mayo implements the MAYO post-quantum signature scheme (NIST PQC round 2 parameters), a whipped Oil-and-Vinegar multivariate signature over GF(16).
It is a pure-Go port of the MAYO reference (PQCMayo/MAYO-C, cross-checked against the pq-mayo Rust crate) and is validated against the official MAYO round 2 known-answer tests. It has no dependencies beyond the Go standard library and this repository's crypto/gf16, so it builds for every GOOS=tamago target.
Example ¶
Sign a message with MAYO-1 and verify it. Key generation and signing are deterministic in the seed and randomizer, mirroring the reference flow where the NIST DRBG supplies both.
package main
import (
"fmt"
"github.com/maceip/tamayo/mayo"
)
func main() {
seed := make([]byte, mayo.Mayo1.SKSeedBytes)
randomizer := make([]byte, mayo.Mayo1.SaltBytes)
cpk, csk, err := mayo.Mayo1.CompactKeyGen(seed)
if err != nil {
panic(err)
}
msg := []byte("This is a message.")
sig, err := mayo.Mayo1.Sign(msg, csk, randomizer)
if err != nil {
panic(err)
}
fmt.Println("signature valid:", mayo.Mayo1.Verify(msg, sig, cpk))
fmt.Println("tampered rejected:", !mayo.Mayo1.Verify([]byte("Another message."), sig, cpk))
}
Output: signature valid: true tampered rejected: true
Index ¶
- Variables
- type Params
- func (p *Params) ACols() int
- func (p *Params) CompactKeyGen(seedSK []byte) (cpk, csk []byte, err error)
- func (p *Params) ExpandPK(cpk []byte) ([]byte, error)
- func (p *Params) KeyGen(rand io.Reader) (cpk, csk []byte, err error)
- func (p *Params) P1Limbs() int
- func (p *Params) P2Limbs() int
- func (p *Params) P3Limbs() int
- func (p *Params) Sign(msg, csk, randomizer []byte) ([]byte, error)
- func (p *Params) SignWithoutHashing(t, csk []byte) []byte
- func (p *Params) V() int
- func (p *Params) Verify(msg, sig, cpk []byte) bool
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ( Mayo1 = Params{ Name: "MAYO_1", N: 86, M: 78, O: 8, K: 10, MVecLimbs: 5, MBytes: 39, OBytes: 312, VBytes: 39, RBytes: 40, P1Bytes: 120159, P2Bytes: 24336, P3Bytes: 1404, CSKBytes: 24, CPKBytes: 1420, SigBytes: 454, SaltBytes: 24, DigestBytes: 32, PKSeedBytes: 16, SKSeedBytes: 24, FTail: [4]byte{8, 1, 1, 0}, } Mayo2 = Params{ Name: "MAYO_2", N: 96, M: 64, O: 16, K: 4, MVecLimbs: 4, MBytes: 32, OBytes: 640, VBytes: 40, RBytes: 32, P1Bytes: 103680, P2Bytes: 40960, P3Bytes: 4352, CSKBytes: 24, CPKBytes: 4368, SigBytes: 216, SaltBytes: 24, DigestBytes: 32, PKSeedBytes: 16, SKSeedBytes: 24, FTail: [4]byte{8, 0, 2, 8}, } Mayo3 = Params{ Name: "MAYO_3", N: 118, M: 108, O: 10, K: 11, MVecLimbs: 7, MBytes: 54, OBytes: 540, VBytes: 54, RBytes: 55, P1Bytes: 317844, P2Bytes: 58320, P3Bytes: 2970, CSKBytes: 32, CPKBytes: 2986, SigBytes: 681, SaltBytes: 32, DigestBytes: 48, PKSeedBytes: 16, SKSeedBytes: 32, FTail: [4]byte{8, 0, 1, 7}, } Mayo5 = Params{ Name: "MAYO_5", N: 154, M: 142, O: 12, K: 12, MVecLimbs: 9, MBytes: 71, OBytes: 852, VBytes: 71, RBytes: 72, P1Bytes: 720863, P2Bytes: 120984, P3Bytes: 5538, CSKBytes: 40, CPKBytes: 5554, SigBytes: 964, SaltBytes: 40, DigestBytes: 64, PKSeedBytes: 16, SKSeedBytes: 40, FTail: [4]byte{4, 0, 8, 1}, } )
The four MAYO round 2 parameter sets.
Functions ¶
This section is empty.
Types ¶
type Params ¶
type Params struct {
Name string
N int // total variables
M int // equations
O int // oil dimension
K int // whipping parameter
MVecLimbs int // u64 limbs per m-vector (bitsliced form)
MBytes int // m field elements, nibble-packed
OBytes int // O matrix, nibble-packed
VBytes int // vinegar vector, nibble-packed
RBytes int // random vector r, nibble-packed
P1Bytes int
P2Bytes int
P3Bytes int
CSKBytes int // compact secret key
CPKBytes int // compact public key
SigBytes int
SaltBytes int
DigestBytes int
PKSeedBytes int
SKSeedBytes int
FTail [fTailLen]byte // tail coefficients of the irreducible f(X)
}
Params holds the constants of one MAYO parameter set.
Field element count is over GF(16); byte sizes below are the nibble-packed serializations used by the reference.
func (*Params) CompactKeyGen ¶
CompactKeyGen derives a compact keypair from a secret seed of SKSeedBytes, as MAYO-C mayo_keypair does from its DRBG output. Deterministic in seedSK.
func (*Params) ExpandPK ¶
ExpandPK expands the compact public key into the full bitsliced public map P1 ‖ P2 ‖ P3 serialized as little-endian uint64 limbs — byte-identical to MAYO-C mayo_expand_pk's output buffer, and the epk format the pomfrit blind-signature engine consumes.
func (*Params) Sign ¶
Sign produces a MAYO signature (SigBytes: s ‖ salt) on msg under csk. The salt is derived from randomizer (SaltBytes), matching the reference flow where the NIST DRBG supplies it; fixing randomizer makes signing deterministic and reproduces the NIST KAT signatures byte-for-byte.
func (*Params) SignWithoutHashing ¶
SignWithoutHashing is the MAYO preimage sampler used by One-More-MAYO's blind sign_2. Transpiled from pq_blind_signatures mayo-c-sys mayo_without_hashing.c (mayo_sign_signature_without_hashing): the standard MAYO signer with the message->digest->salt->t hashing chain removed. The target t is supplied directly (m_bytes, nibble-encoded), the vinegar is V = SHAKE256(t || seed_sk || ctr) with NO salt, and the output is encode(s) of length sig_bytes - salt_bytes (no salt appended).
It returns a preimage s (the blinded MAYO signature) with eval_public_map(s) == decode(t), i.e. the vole witness s-part for the ZK proof.
t is attacker-controlled in the blind protocol (the user supplies it), so a wrong-sized t or csk returns nil instead of panicking.