mirror of
https://github.com/sonr-io/crypto.git
synced 2026-09-17 01:26:23 +00:00
164 lines
6.1 KiB
Plaintext
164 lines
6.1 KiB
Plaintext
---
|
|
title: Getting started
|
|
description: Install the module, choose a curve, and learn the conventions — constructors, round-based protocols, serialization, and error handling — that every package in this library shares.
|
|
sidebar:
|
|
label: Getting started
|
|
order: 1
|
|
icon: rocket
|
|
---
|
|
|
|
## Install
|
|
|
|
```bash
|
|
go get github.com/sonr-io/crypto
|
|
```
|
|
|
|
Requires **Go 1.24.7 or newer**. Every package is imported under the module path
|
|
`github.com/sonr-io/crypto/<package>`:
|
|
|
|
```go
|
|
import (
|
|
"github.com/sonr-io/crypto/core/curves"
|
|
"github.com/sonr-io/crypto/sharing"
|
|
"github.com/sonr-io/crypto/mpc"
|
|
)
|
|
```
|
|
|
|
There is no top-level façade package — the module root holds only a cross-package security test suite.
|
|
Import the specific primitive you need.
|
|
|
|
## Pick a curve first
|
|
|
|
Most constructors take a `*curves.Curve`. That single argument determines the group, the scalar
|
|
field, and the serialization width of everything downstream, so it is the first decision you make:
|
|
|
|
```go
|
|
curve := curves.K256() // secp256k1 — Bitcoin, Ethereum, Cosmos
|
|
curve := curves.P256() // NIST P-256 — WebAuthn, FIDO2, TLS
|
|
curve := curves.ED25519() // Ed25519 — Sonr identity keys
|
|
```
|
|
|
|
Some primitives need a **pairing-friendly** curve instead, because they rely on a bilinear map.
|
|
BBS+ signatures and the accumulator both fall in this group and take a `*curves.PairingCurve`:
|
|
|
|
```go
|
|
pairingCurve := curves.BLS12381(curves.BLS12381G1().NewGeneratorPoint())
|
|
```
|
|
|
|
Passing a plain `*curves.Curve` where a `*curves.PairingCurve` is required will not compile, which is
|
|
the intended guardrail. See [Curves](/foundations/curves) for the full catalog and interface reference.
|
|
|
|
:::note
|
|
Curve choice is rarely free to change later. A key generated on secp256k1 has no meaning on Ed25519,
|
|
and stored shares, commitments, and serialized proofs are all curve-specific.
|
|
:::
|
|
|
|
## Conventions worth knowing
|
|
|
|
### Constructors validate, so check the error
|
|
|
|
Constructors do real work — parameter validation, generator derivation, table precomputation — and
|
|
return an `error` rather than panicking on bad input. A `NewShamir` with a threshold above its limit
|
|
fails at construction, not at `Split` time:
|
|
|
|
```go
|
|
scheme, err := sharing.NewShamir(3, 5, curves.K256())
|
|
if err != nil {
|
|
return fmt.Errorf("invalid sharing parameters: %w", err)
|
|
}
|
|
```
|
|
|
|
### Two generations of API coexist
|
|
|
|
The library carries an older, curve-specific API alongside the modern generic one. You will meet both
|
|
in `go doc` output, and mixing them does not type-check:
|
|
|
|
| Modern | Legacy | Used by |
|
|
| --- | --- | --- |
|
|
| `curves.Point`, `curves.Scalar` | `curves.EcPoint`, `curves.EcScalar` | `sharing/v1`, `dkg/gennaro` |
|
|
| `sharing` | `sharing/v1` | `dkg/gennaro`, `dkg/gennaro2p` |
|
|
| operates on `curves.Scalar` | operates on `[]byte` and `curves.Element` | — |
|
|
|
|
Prefer the modern API for new code. Reach for the legacy layer only when a package you depend on
|
|
forces it. [Foundations](/foundations) explains the split in detail.
|
|
|
|
### Multi-party protocols are explicit round objects
|
|
|
|
Nothing in this library hides the network. A multi-party protocol is a stateful object whose methods
|
|
are the rounds, and you move the messages between parties yourself. Two shapes appear:
|
|
|
|
<Tabs>
|
|
<Tab title="Named rounds">
|
|
Each round is a distinct method. You call them in order and route the outputs — some broadcast to
|
|
everyone, some point-to-point to one peer. Used by [`dkg/frost`](/threshold/dkg),
|
|
[`dkg/gennaro`](/threshold/dkg), and [`ted25519/frost`](/threshold/threshold-ed25519).
|
|
|
|
```go
|
|
bcast, p2p, err := participant.Round1(secret)
|
|
// broadcast `bcast` to all; send p2p[peerID] privately to each peer
|
|
```
|
|
</Tab>
|
|
<Tab title="Iterator crank">
|
|
The protocol is a `protocol.Iterator`: you feed it the counterparty's message and it returns the
|
|
next one, until it signals completion and you read `Result`. Used by
|
|
[`tecdsa/dklsv1`](/threshold/threshold-ecdsa) and, wrapped up entirely, by
|
|
[`mpc`](/identity/mpc-enclave).
|
|
|
|
```go
|
|
msg, err := alice.Next(bobMsg)
|
|
```
|
|
</Tab>
|
|
</Tabs>
|
|
|
|
Calling rounds out of order is an error, not undefined behavior — the objects track their own state.
|
|
See [Protocol messages](/foundations/protocol) for the iterator contract.
|
|
|
|
### Serialization is per-type, not reflective
|
|
|
|
Keys, shares, proofs, and signatures implement their own codecs — usually
|
|
`MarshalBinary`/`UnmarshalBinary`, sometimes `MarshalJSON`/`UnmarshalJSON`, and in the DKG packages
|
|
`Encode`/`Decode`. Use them rather than reflecting over struct fields with `encoding/gob` or a
|
|
generic JSON marshal, because unexported field state and curve identity would be lost.
|
|
|
|
Unmarshalling frequently needs to know the curve up front, since the wire bytes alone do not identify
|
|
it. The idiom is to initialize an empty value on the right curve, then unmarshal into it:
|
|
|
|
```go
|
|
sig := new(bbs.Signature).Init(pairingCurve)
|
|
if err := sig.UnmarshalBinary(data); err != nil {
|
|
return err
|
|
}
|
|
```
|
|
|
|
### Randomness is injected
|
|
|
|
Anything that consumes entropy takes an `io.Reader`, so tests can be deterministic and production
|
|
code is explicit about its source. Pass `crypto/rand.Reader` unless you have a specific reason not to:
|
|
|
|
```go
|
|
shares, err := scheme.Split(secret, rand.Reader)
|
|
```
|
|
|
|
:::danger
|
|
A deterministic or repeated reader in production is a key-recovery bug, not a performance
|
|
optimization. Several protocols here — Ed25519 nonce generation especially — leak the signing key
|
|
outright if the same randomness is used for two different messages.
|
|
:::
|
|
|
|
## Where to next
|
|
|
|
<CardGroup cols={2}>
|
|
<Card title="Foundations" href="/foundations" icon="layers">
|
|
The curve, point, and scalar model that the rest of the library is written against.
|
|
</Card>
|
|
<Card title="Package index" href="/reference/packages" icon="list">
|
|
Every importable package and the page that documents it.
|
|
</Card>
|
|
<Card title="Security notes" href="/reference/security" icon="shield-alert">
|
|
Stubs, known defects, and non-constant-time paths found while documenting the code.
|
|
</Card>
|
|
<Card title="MPC enclave" href="/identity/mpc-enclave" icon="shield">
|
|
The highest-level entry point: threshold ECDSA as a single value.
|
|
</Card>
|
|
</CardGroup>
|