Use from Go
The Go package compiles the C library into itself with cgo, from a copy of the sources in the module: it needs a C compiler (gcc or clang; on Windows, MinGW-w64 gcc) and nothing else. It builds on Linux, macOS and Windows.
go get github.com/rootcoder007/noqtis/bindings/goimport "github.com/rootcoder007/noqtis/bindings/go" // package noqtisSeal and check a folder
Section titled “Seal and check a folder”This is Example_seal in the package’s example_test.go; go test
runs it and checks what it prints:
// a folder with some resultsd, _ := os.MkdirTemp("", "noqtis-go-demo")defer os.RemoveAll(d)os.MkdirAll(filepath.Join(d, "data"), 0o755)os.WriteFile(filepath.Join(d, "data", "in.csv"), []byte("a,b\n1,2\n"), 0o644)os.WriteFile(filepath.Join(d, "report.txt"), []byte("r\n"), 0o644)
// seal it, then check it with the public key pinnedpk, sk, _ := noqtis.SignKeyGen("ML-DSA-65", nil)if err := noqtis.Seal(d, "ML-DSA-65", sk, pk, `{"project":"tutorial"}`); err != nil { panic(err)}o := &noqtis.CheckOpts{Trust: pk}r, err := noqtis.Check(d, o)if err != nil { panic(err)}fmt.Printf("check: %v (%d checks)\n", r.OK(), len(r.Rows))
// change a file: the check fails and says whyos.WriteFile(filepath.Join(d, "report.txt"), []byte("r\nedited\n"), 0o644)r, _ = noqtis.Check(d, o)fmt.Println("after edit:", r.OK())for _, row := range r.Failed() { fmt.Println("FAIL", row.Check, row.Detail)}It prints:
check: true (22 checks)after edit: falseFAIL file report.txt: size differsSealwritesnoqtis.jsonandnoqtis.siginto the folder;metais JSON text (an object), signed with the manifest and never interpreted.Seal2seals in format 2, with the capsules it was made from.Checkreturns a*Reportalso when the capsule fails:OK()is true only when every check passed, andRowslists every check. WithoutTrustit accepts the key in the seal, and thekeyrow says so.Inspect,CapID,ProveandCheckProofdo whatnoqtis inspect, the capsule id,noqtis proveandnoqtis check --proofdo.
Sign and verify
Section titled “Sign and verify”Example_sign:
pk, sk, err := noqtis.SignKeyGen("ML-DSA-65", nil)if err != nil { panic(err)}o := &noqtis.SignOpts{Ctx: []byte("app-v1")}msg := []byte("the results in table 2")sig, err := noqtis.Sign("ML-DSA-65", sk, msg, o)if err != nil { panic(err)}fmt.Println("signature:", len(sig), "bytes")ok, _ := noqtis.Verify("ML-DSA-65", pk, msg, sig, o)fmt.Println("verify:", ok)ok, _ = noqtis.Verify("ML-DSA-65", pk, []byte("other"), sig, o)fmt.Println("other message:", ok)signature: 3309 bytesverify: trueother message: falseVerify returns false, nil for a bad signature; only a bad argument is
an error. Every error is an *noqtis.Error with the library’s code
(Code) and message (Msg, from nqerr); errors.Is(err, noqtis.ErrVerify) and its siblings match by code.
Identity cards
Section titled “Identity cards”An identity card ties your signing key to who you are, signed by the
key itself; noqtis check --card reads it too. Example_card:
pk, sk, err := noqtis.SignKeyGen("ML-DSA-65", nil)if err != nil { panic(err)}f := noqtis.CardFields{Name: "Ada Lovelace", ORCID: "https://orcid.org/0000-0002-1825-0097", URL: "https://example.org/ada"}card, err := noqtis.MakeCard("ML-DSA-65", sk, pk, f, time.Time{})if err != nil { panic(err)}c, _ := noqtis.VerifyCard(card, pk) // nil unless it verifies and is pk'sfmt.Println("name:", c.Name)fmt.Println("orcid:", c.ORCID)
// a changed card does not verify; a wrong check digit is refusedbad := bytes.Replace(card, []byte("Ada"), []byte("Eve"), 1)c, _ = noqtis.VerifyCard(bad, nil)fmt.Println("changed:", c == nil)f.ORCID = "0000-0002-1825-0098"_, err = noqtis.MakeCard("ML-DSA-65", sk, pk, f, time.Time{})fmt.Println("refused:", errors.Is(err, noqtis.ErrArg))name: Ada Lovelaceorcid: 0000-0002-1825-0097changed: truerefused: trueThe card holds the bare ORCID iD. It is self-signed: it shows that the
holder of the key wrote it, not that the name is true, so give the key’s
SHA-256 (KeySHA256) where people already know you, or let readers pin
your public key. VerifyCard returns nil, nil for a card that does
not verify or is for another key, and ErrDecode for input that is not
a card.
KEMKeyGen,EncapandDecapdo key encapsulation;Hash,HashN,HMACandRandomthe rest;ReadKeyandWriteKeyread and write the CLI’s key files.- Secret keys are plain
[]byte: overwrite them yourself when that matters.
The full API is in the package’s README.