rscrypto 0.8.0

Pure Rust Cryptography: RSA, Ed25519, X25519, SHA-2/3, BLAKE2/3, AES-GCM/GCM-SIV, X/ChaCha20-Poly1305, Argon2, HMAC/HKDF, CRC. no_std, WASM, hardware acceleration.
Documentation
# Release Process

`rscrypto` releases are approved by the maintainer and published by CI.
`cargo-rail` prepares a release pull request and creates the signed tag. GitHub
Actions builds, attests, and publishes the artifacts. A normal release must
never run `cargo publish` locally.

## Release at a glance

1. Start from a clean, current `main` after all intended feature pull requests
   have merged. Every user-visible change must already have a reviewed
   `.changes/*.md` file.

   ```bash
   git switch main
   git pull --ff-only
   git status --short
   cargo rail change status
   cargo rail release check rscrypto --extended
   ```

2. Prepare the release:

   ```bash
   just release-prepare
   ```

   This creates a `rail/release-*` branch, commits the generated version and
   changelog, opens a pull request, refreshes the standalone constant-time tool
   lockfiles, and pushes that follow-up commit. It does not tag or publish.
   The adapter is required because Cargo Rail does not yet include auxiliary
   workspace lockfiles in its release mutation. Running `cargo rail release
   run rscrypto --bump auto --yes --pr` directly would leave the CT workspaces
   stale under `--locked`.

3. Wait for the release pull request's required `Complete` check. Review the
   version, changelog, and lockfile diff, then merge it in the GitHub UI.

4. Record the exact merged release candidate:

   ```bash
   git switch main
   git pull --ff-only
   candidate=$(git rev-parse HEAD)
   ```

5. Dispatch the expensive release evidence on that commit. Do this before
   another pull request merges into `main`. Release mode reruns the complete CI
   suite, including compiler-backed Cargo graph assurance, and retains raw CT
   evidence for 90 days.

   ```bash
   gh workflow run weekly.yaml --ref main -f mode=release
   gh workflow run riscv.yaml --ref main -f mode=evidence
   ```

   Confirm that both runs report `$candidate` as their head SHA. If code,
   dependencies, features, build inputs, or test policy change afterward, rerun
   both workflows. Do not substitute a scheduled Weekly or RISC-V run, or an
   assurance-mode Weekly dispatch: those produce compact reports with 14-day
   retention and cannot satisfy the release evidence gate.

6. After both exact-commit evidence workflows are green, create and push the
   signed tag:

   ```bash
   test "$(git rev-parse HEAD)" = "$candidate"
   just release-tag
   ```

   `release-tag` rechecks live repository controls and exact-commit release
   evidence before allowing the tag. It never publishes to crates.io locally.

7. The tag starts the `Release` workflow. Approve its `crates-io` environment
   job after the prerequisite jobs pass. CI publishes and verifies the immutable
   GitHub Release before publishing the same crate through crates.io Trusted
   Publishing.

8. Run the commands in [Verification]#verification.

## Why each gate exists

| Gate | What it prevents |
|---|---|
| Release pull request | An unreviewed version or changelog mutation reaching protected `main`. |
| Exact-commit Weekly release mode | Tagging a candidate without an explicitly requested full suite, compiler-backed Cargo graph assurance, raw CT artifacts, and complete CT/RSA gates. |
| Weekly and RISC-V evidence | Publishing cryptographic claims without the required platform and timing evidence. |
| Signed immutable tag | Moving a released version to different source later. |
| Immutable, attested GitHub Release | Publishing artifacts that cannot be tied back to the tag and build. |
| Environment approval | A tag or compromised workflow publishing to crates.io without a final human decision. |
| Trusted Publishing | Long-lived crates.io credentials becoming a repository secret. |

Pull-request CI answers "may this change merge?" once. Scheduled Weekly assurance
keeps routine safety coverage current with compact, short-lived reports. Only a
manually dispatched exact-commit Weekly release run and RISC-V evidence answer
"may this protected-branch commit become a release?"

## One-time setup

Configure the crate on crates.io:

| Field | Value |
|---|---|
| Repository owner | `loadingalias` |
| Repository name | `rscrypto` |
| Workflow filename | `release.yaml` |
| Environment | `crates-io` |

After the first successful Trusted Publishing release, enable crates.io
Trusted Publishing Only Mode for `rscrypto`. That disables traditional API
token publishing for new versions.

Configure the GitHub repository:

1. Activate the `protect-main` branch ruleset described by
   [`.github/rulesets/protect-main.json`]../.github/rulesets/protect-main.json,
   with no bypass actors.
2. Activate the `protect-release-tags` tag ruleset described by
   [`.github/rulesets/protect-release-tags.json`]../.github/rulesets/protect-release-tags.json,
   with no bypass actors. It permits a new `v*` tag but prevents updating or
   deleting an existing one.
3. In **Settings → General → Releases**, enable release immutability as described
   by [`.github/repository-settings/release-immutability.json`]../.github/repository-settings/release-immutability.json.
   It applies only to releases published after the setting is enabled.
4. Create an environment named `crates-io` and add the current maintainer as its
   required reviewer. Permit self-review while the project has one maintainer,
   but disable administrator bypass. Require independent approval after a second
   trusted maintainer exists.
5. Keep long-lived crates.io publish tokens out of repository secrets.

The environment name must match crates.io and
[`.github/workflows/release.yaml`](../.github/workflows/release.yaml), or the
OIDC token exchange will fail.

## Release intent

Commit a cargo-rail change file with each user-visible change when possible.
Change files live in `.changes/`; their reviewed bodies become the changelog.
Commit subjects remain engineering history, not release notes.

```bash
cargo rail change add rscrypto --bump patch --message "Describe the user-visible result."
cargo rail change status
```

Use `minor` or `major` when compatibility requires it. Before preparing a
release, `cargo rail release check rscrypto --extended` validates the pending
release and its SemVer contract.

Pull-request CI uses cargo-rail's planner to select checks from the actual
changed surfaces. Weekly release mode runs the full Cargo graph proof for an
exact release candidate; scheduled assurance does not. Release preflight
consumes the release-mode result instead of recompiling it.

`release-prepare` delegates the version, changelog, branch, commit, and pull
request to Cargo Rail, then synchronizes the three standalone CT lockfiles.
After that pull request merges, `release-tag` deliberately does not rerun the
consumed pending-intent check. It proves live repository controls and
exact-commit release evidence before using `cargo rail release finalize
--skip-publish` to create and push the signed tag.

To inspect live repository controls without starting a release:

```bash
scripts/ci/repository-controls-evidence.sh \
  --commit "$(git rev-parse HEAD)" \
  --output target/repository-controls.json
```

This is the only routine local check that reads live GitHub settings. It writes
the captured JSON to `target/repository-controls.json`; normal checks and
pre-push validation remain offline.

## What the tag workflow verifies

Pushing a `vX.Y.Z` tag starts the `Release` workflow. Before crates.io can
receive anything, the workflow:

1. Verifies the annotated SSH signature, tag target, crate version, and
   changelog version.
2. Revalidates configuration, dependency policy, audit results, SemVer, and the
   exact-commit Weekly release-mode Cargo graph result.
3. Requires the Weekly release gate, live raw CT artifacts, complete Weekly
   CT/RSA, and manually dispatched RISC-V native/CT evidence from that exact
   commit and crate version.
4. Builds the `.crate` once, reproduces the source archive from the tag, and
   rejects dirty, private, local-only, or mismatched package contents.
5. Captures repository controls and writes provenance attestations, an identity
   manifest, and `SHA256SUMS` for the artifacts and evidence.
6. Publishes and verifies the immutable GitHub Release, obtains a temporary
   crates.io token through OIDC, publishes the same crate, then downloads it
   from crates.io and verifies its SHA-256.

Any change after the evidence run—including a version-only or release-tooling
change—creates a new release candidate and requires fresh paired Weekly and
RISC-V evidence. Ancestor binaries are never promoted into an exact-commit
constant-time claim.

## Recovery

After a partial failure, rerun the workflow on the same tag and commit. If
crates.io already contains the version, the workflow downloads it and compares
its SHA-256 before touching the GitHub Release. The workflow can repair and
publish a draft release. It never overwrites a published immutable release; it
verifies the release attestation and stable crate and source assets before
publishing to crates.io. Any mismatch stops the release.

If the signed-tag key changes, update `.github/allowed-signers` in a reviewed
commit before creating the next release tag.

## Verification

Consumers can verify the GitHub Release artifact:

```bash
gh release download vX.Y.Z --repo loadingalias/rscrypto \
  -p 'rscrypto-X.Y.Z.crate' \
  -p 'rscrypto-X.Y.Z-source.tar.gz' \
  -p 'rscrypto-X.Y.Z-ct-evidence.tar.gz' \
  -p 'rscrypto-X.Y.Z-repository-controls.json' \
  -p 'rscrypto-X.Y.Z-release-manifest.json' \
  -p SHA256SUMS
sha256sum --check SHA256SUMS
gh release verify vX.Y.Z --repo loadingalias/rscrypto
gh release verify-asset vX.Y.Z rscrypto-X.Y.Z.crate --repo loadingalias/rscrypto
gh release verify-asset vX.Y.Z rscrypto-X.Y.Z-source.tar.gz --repo loadingalias/rscrypto
gh attestation verify rscrypto-X.Y.Z.crate --repo loadingalias/rscrypto
gh attestation verify rscrypto-X.Y.Z-source.tar.gz --repo loadingalias/rscrypto
gh attestation verify rscrypto-X.Y.Z-ct-evidence.tar.gz --repo loadingalias/rscrypto
gh attestation verify rscrypto-X.Y.Z-repository-controls.json --repo loadingalias/rscrypto
gh attestation verify rscrypto-X.Y.Z-release-manifest.json --repo loadingalias/rscrypto
gh attestation verify SHA256SUMS --repo loadingalias/rscrypto
ct_evidence_dir=$(mktemp -d)
tar -xzf rscrypto-X.Y.Z-ct-evidence.tar.gz -C "$ct_evidence_dir"
(cd "$ct_evidence_dir" && sha256sum --check CT-EVIDENCE-MANIFEST.txt)
```

The crate downloaded from crates.io must have the same SHA-256 as the attested
release artifact. The release identity manifest joins the release source,
artifacts, evidence, and toolchain. The repository-controls JSON records the
expected policies, immutable-release setting, live branch and tag rulesets,
effective default-branch rules, capture time, and release commit. Its
validation fields state whether the capturing token could inspect each bypass
list and the immutable-release setting. The JSON records release-time
configuration; GitHub settings can change afterward.