Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 19 additions & 18 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -33,37 +33,38 @@ test-backward-compatibility: pull-lfs-files
test-backward-compatibility-local:
cargo test --test backward_compatibility_* -- --include-ignored --no-capture

# Frozen — generators may be non-deterministic. Their data is committed and
# must NOT be deleted or regenerated by `generate-backward-compatibility-all`.
FROZEN_BWC_VERSIONS := 0.11.0 0.11.1 0.13.0 0.13.10 0.13.20

# Deterministic — re-running produces byte-identical output.
# `generate-backward-compatibility-all` cleans and regenerates these.
DETERMINISTIC_BWC_VERSIONS := 0.14.0

# Derived data-dir paths (e.g. 0.14.0 -> backward-compatibility/data/0_14_0)
DETERMINISTIC_BWC_DIRS := $(addprefix backward-compatibility/data/,$(subst .,_,$(DETERMINISTIC_BWC_VERSIONS)))

clean-backward-compatibility-data:
rm -f backward-compatibility/data/kms.ron
rm -f backward-compatibility/data/kms-grpc.ron
rm -f backward-compatibility/data/threshold-fhe.ron
rm -rf backward-compatibility/data/0_11_0
rm -rf backward-compatibility/data/0_11_1
rm -rf backward-compatibility/data/0_13_0
rm -rf backward-compatibility/data/0_13_10
rm -rf backward-compatibility/data/0_13_20
rm -rf backward-compatibility/data/0_14_0

generate-backward-compatibility-v0.11.0:
cd backward-compatibility/generate-v0.11.0 && cargo run --release

generate-backward-compatibility-v0.11.1:
cd backward-compatibility/generate-v0.11.1 && cargo run --release
@# Only deterministic-version dirs are removed. Frozen dirs and the shared
@# .ron files are preserved so committed frozen entries survive.
@if [ -n "$(DETERMINISTIC_BWC_DIRS)" ]; then rm -rf $(DETERMINISTIC_BWC_DIRS); fi
Comment on lines +36 to +50
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed in 904f248


# Use the version-specific generators only if you really need it,
# e.g., when a type is added in a minor release.
generate-backward-compatibility-v0.13.0:
cd backward-compatibility/generate-v0.13.0 && cargo run --release

generate-backward-compatibility-v0.13.10:
cd backward-compatibility/generate-v0.13.10 && cargo run --release

generate-backward-compatibility-v0.13.20:
cd backward-compatibility/generate-v0.13.20 && cargo run --release

generate-backward-compatibility-v0.14.0:
cd backward-compatibility/generate-v0.14.0 && cargo run --release

generate-backward-compatibility-all: clean-backward-compatibility-data generate-backward-compatibility-v0.11.0 generate-backward-compatibility-v0.11.1 generate-backward-compatibility-v0.13.0 generate-backward-compatibility-v0.13.10 generate-backward-compatibility-v0.13.20 generate-backward-compatibility-v0.14.0
@echo "Generated backward compatibility data for all versions"
generate-backward-compatibility-all: clean-backward-compatibility-data $(addprefix generate-backward-compatibility-v,$(DETERMINISTIC_BWC_VERSIONS))
@echo "Generated backward compatibility data for deterministic versions: $(DETERMINISTIC_BWC_VERSIONS)"

# Test material generation targets
generate-test-material-all:
Expand Down
18 changes: 10 additions & 8 deletions ai-docs/COMMANDS.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,24 +80,26 @@ Direct cargo invocation (what the make targets call under the hood):
cargo test --test 'backward_compatibility_*' -- --include-ignored
```

Regenerate vectors for all historical versions (cleans first, then runs each generator):
Regenerate vectors. Versions are split into two lists in the `Makefile`:

- `FROZEN_BWC_VERSIONS` — currently `0.11.0`, `0.11.1`, `0.13.0`, `0.13.10`, `0.13.20`. Generators were non-deterministic across runs, so the committed `.bcode` files and `.ron` entries are the source of truth and must not be regenerated as part of normal workflow.
- `DETERMINISTIC_BWC_VERSIONS` — `0.14.0` and future versions. Re-running produces byte-identical output.

Regenerate all deterministic versions (cleans only deterministic data dirs first, then runs their generators; frozen versions are left untouched):

```
make generate-backward-compatibility-all
```

Regenerate for a single version. **Warning**: removes other versions' entries from the `.ron` files — do not commit the result:
Regenerate for a single deterministic version:

```
make generate-backward-compatibility-v0.11.0
make generate-backward-compatibility-v0.11.1
make generate-backward-compatibility-v0.13.0
make generate-backward-compatibility-v0.13.10
make generate-backward-compatibility-v0.13.20
make generate-backward-compatibility-v0.14.0
```

Clean all generated BC data:
Per-version targets also exist for the frozen versions `v0.13.0`, `v0.13.10`, and `v0.13.20` (no targets for `v0.11.0` / `v0.11.1` — their generator crates are kept only for historical inspection). These frozen-version targets are for exceptional investigation only; running them can produce non-deterministic bytes and append duplicate metadata to the shared `.ron` files, so their output must not be committed.

Remove generated BC data for deterministic versions only — frozen data dirs and all shared `.ron` files are preserved:

```
make clean-backward-compatibility-data
Expand Down
105 changes: 50 additions & 55 deletions backward-compatibility/ADDING_NEW_VERSIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,18 @@

## Quick Start

When adding a new KMS version (e.g., v0.12.0), follow these steps:
When adding a new KMS version (e.g., v0.14.0), follow these steps:

### Step 1: Check Dependency Compatibility

Before adding a new version, verify it's compatible with existing generator versions:

```bash
# Check key dependencies in the new release
curl -s "https://raw.githubusercontent.com/zama-ai/kms/v0.12.0/Cargo.toml" | grep -E "serde|alloy|tfhe"
curl -s "https://raw.githubusercontent.com/zama-ai/kms/v0.14.0/Cargo.toml" | grep -E "serde|alloy|tfhe"

# Compare with the most recent generator (v0.11.1)
grep -E "serde|alloy|tfhe" backward-compatibility/generate-v0.11.1/Cargo.toml
# Compare with the most recent deterministic generator (currently v0.14.0)
grep -E "serde|alloy|tfhe" backward-compatibility/generate-v0.14.0/Cargo.toml
```

**Key dependencies to check:**
Expand All @@ -24,20 +24,22 @@ grep -E "serde|alloy|tfhe" backward-compatibility/generate-v0.11.1/Cargo.toml

### Step 2A: If Dependencies Are Compatible

Add the version to the most recent compatible generator (e.g., `generate-v0.11.1`):
Add the version to the most recent compatible deterministic generator (e.g., `generate-v0.14.0`):

1. **Add dependencies** to `backward-compatibility/generate-v0.11.1/Cargo.toml`:
1. **Add dependencies** to `backward-compatibility/generate-v0.14.0/Cargo.toml`:
```toml
kms_0_12_0 = { git = "https://github.com/zama-ai/kms.git", package = "kms", rev = "v0.12.0" }
kms_grpc_0_12_0 = { git = "https://github.com/zama-ai/kms.git", package = "kms-grpc", rev = "v0.12.0" }
threshold_fhe_0_12_0 = { git = "https://github.com/zama-ai/kms.git", package = "threshold-fhe", rev = "v0.12.0", features = ["testing"] }
kms_0_14_0 = { git = "https://github.com/zama-ai/kms.git", package = "kms", rev = "v0.14.0" }
kms_grpc_0_14_0 = { git = "https://github.com/zama-ai/kms.git", package = "kms-grpc", rev = "v0.14.0" }
threshold_fhe_0_14_0 = { git = "https://github.com/zama-ai/kms.git", package = "threshold-fhe", rev = "v0.14.0", features = ["testing"] }
```

2. **Create** `backward-compatibility/generate-v0.11.1/src/data_0_12.rs` implementing `KMSCoreVersion` trait
2. **Create** `backward-compatibility/generate-v0.14.0/src/data_0_14.rs` implementing `KMSCoreVersion` trait

3. **Update** `backward-compatibility/generate-v0.11.1/src/main.rs` to generate data for v0.12.0
3. **Update** `backward-compatibility/generate-v0.14.0/src/main.rs` to generate data for v0.14.0

4. **Update** root `Makefile` to add v0.12.0 target (optional, for individual generation)
4. **Update** root `Makefile`:
- Add v0.14.0 to `DETERMINISTIC_BWC_VERSIONS`
- Add a `generate-backward-compatibility-v0.14.0` target if this version has its own generator crate

5. **Generate the data**:
```bash
Expand All @@ -50,59 +52,53 @@ make generate-backward-compatibility-all
make test-backward-compatibility-local
```

⚠️ **Important**: Always use `make generate-backward-compatibility-all` to ensure all versions are regenerated with merged metadata!
⚠️ **Important**: Always use `make generate-backward-compatibility-all` for normal regeneration. It skips frozen versions and refreshes only the deterministic versions listed in `DETERMINISTIC_BWC_VERSIONS`.

### Step 2B: If Dependencies Are Incompatible

Create a new generator crate for the incompatible version:

1. **Copy the most recent generator**:
1. **Copy the closest previous generator**:
```bash
cp -r backward-compatibility/generate-v0.11.1 backward-compatibility/generate-v0.12.0
cp -r backward-compatibility/generate-v0.13.20 backward-compatibility/generate-v0.14.0
```

2. **Update** `backward-compatibility/generate-v0.12.0/Cargo.toml`:
- Package name: `backward-compatibility-generate-v0-12-0` (use dashes, include patch version)
- Package version: `0.12.0` (matches the KMS version exactly)
- Update all KMS dependencies to v0.12.0
- Update dependency versions (serde, alloy, tfhe) to match v0.12.0's requirements
2. **Update** `backward-compatibility/generate-v0.14.0/Cargo.toml`:
- Package name: `backward-compatibility-generate-v0-14-0` (use dashes, include patch version)
- Package version: `0.14.0` (matches the KMS version exactly)
- Update all KMS dependencies to v0.14.0 (or to the release commit if the tag is not available yet)
- Update dependency versions (serde, alloy, tfhe) to match v0.14.0's requirements

3. **Update** `backward-compatibility/generate-v0.12.0/src/data_0_11.rs`:
- Change imports from `kms_0_11_1` to `kms_0_12_0` (or rename file to `data_0_12.rs`)
- Update `VERSION_NUMBER` to `"0.12.0"`
- Fix any API changes between v0.11.1 and v0.12.0
3. **Update** the copied source files:
- Rename `backward-compatibility/generate-v0.14.0/src/data_0_13.rs` to `data_0_14.rs`
- Change imports from `kms_0_13_20`, `kms_grpc_0_13_20`, and sibling aliases to their `0_14_0` names
- Update `VERSION_NUMBER` to `"0.14.0"`
- Update `src/lib.rs` and `src/main.rs` module names and imports to use `data_0_14`
- Fix any API changes between v0.13.20 and v0.14.0

4. **Update** root `Cargo.toml` to exclude the new generator:
```toml
exclude = [
"backward-compatibility",
"backward-compatibility/generate-v0.11.0",
"backward-compatibility/generate-v0.11.1",
"backward-compatibility/generate-v0.12.0" # Add this
"backward-compatibility/generate-v0.13.0",
"backward-compatibility/generate-v0.13.10",
"backward-compatibility/generate-v0.13.20",
"backward-compatibility/generate-v0.14.0", # Add this
]
```

5. **Update** root `Makefile`:
```makefile
generate-backward-compatibility-v0.12.0:
cd backward-compatibility/generate-v0.12.0 && cargo run --release

generate-backward-compatibility-all: clean-backward-compatibility-data \
generate-backward-compatibility-v0.11.0 \
generate-backward-compatibility-v0.11.1 \
generate-backward-compatibility-v0.12.0 # Add this
@echo "✅ Generated backward compatibility data for all versions"
```
DETERMINISTIC_BWC_VERSIONS := 0.14.0

6. **Update** `clean-backward-compatibility-data` target in Makefile:
```makefile
clean-backward-compatibility-data:
rm -f backward-compatibility/data/*.ron
rm -rf backward-compatibility/data/0_11_0
rm -rf backward-compatibility/data/0_11_1
rm -rf backward-compatibility/data/0_12_0 # Add this
generate-backward-compatibility-v0.14.0:
cd backward-compatibility/generate-v0.14.0 && cargo run --release
```

6. **Do not add the new version to `FROZEN_BWC_VERSIONS`** unless the generator is known to be non-deterministic and the generated data is intentionally frozen. `clean-backward-compatibility-data` derives deterministic data directories from `DETERMINISTIC_BWC_VERSIONS`.

7. **Test the new generator**:
```bash
make generate-backward-compatibility-all
Expand All @@ -115,12 +111,12 @@ make test-backward-compatibility-local

| Generator Crate | Package Name | KMS Versions | Key Dependencies | Status |
|----------------|--------------|--------------|------------------|--------|
| `generate-v0.11.0` | `backward-compatibility-generate-v0-11-0` | v0.11.0 | serde 1.0.219, alloy 1.1.2, tfhe 1.3.2 | ✅ Active |
| `generate-v0.11.1` | `backward-compatibility-generate-v0-11-1` | v0.11.1 | serde 1.0.226, alloy 1.3.1, tfhe 1.3.3 | ✅ Active |
| `generate-v0.13.0` | `backward-compatibility-generate-v0-13-0` | v0.13.0 | — | ✅ Active |
| `generate-v0.13.10` | `backward-compatibility-generate-v0-13-10` | v0.13.10 | — | ✅ Active |
| `generate-v0.13.20` | `backward-compatibility-generate-v0-13-20` | v0.13.20 | — | ✅ Active |
| `generate-v0.14.0` | `backward-compatibility-generate-v0-14-0` | v0.14.0 | tfhe-versionable 0.7.0, tfhe 1.6.1, alloy 1.4.1, serde 1.0.228 | ✅ Active |
| `generate-v0.11.0` | `backward-compatibility-generate-v0-11-0` | v0.11.0 | serde 1.0.219, alloy 1.1.2, tfhe 1.3.2 | Frozen |
| `generate-v0.11.1` | `backward-compatibility-generate-v0-11-1` | v0.11.1 | serde 1.0.226, alloy 1.3.1, tfhe 1.3.3 | Frozen |
| `generate-v0.13.0` | `backward-compatibility-generate-v0-13-0` | v0.13.0 | — | Frozen |
| `generate-v0.13.10` | `backward-compatibility-generate-v0-13-10` | v0.13.10 | — | Frozen |
| `generate-v0.13.20` | `backward-compatibility-generate-v0-13-20` | v0.13.20 | — | Frozen |
| `generate-v0.14.0` | `backward-compatibility-generate-v0-14-0` | v0.14.0 | tfhe-versionable 0.7.0, tfhe 1.6.1, alloy 1.4.1, serde 1.0.228 | Deterministic |

**Note**: v0.11.0 and v0.11.1 require separate generators due to incompatible alloy and tfhe versions.

Expand All @@ -137,7 +133,7 @@ Create a new generator crate when:
Before committing, verify the generator builds:

```bash
cd backward-compatibility/generate-v0.11
cd backward-compatibility/generate-v0.14.0
cargo check
cargo build --release
```
Expand All @@ -159,17 +155,16 @@ make generate-backward-compatibility-all
```

This will:
1. Clean old data files
2. Run each generator in sequence (v0.11.0, v0.11.1, etc.)
3. Merge metadata from all versions into combined `.ron` files
1. Clean deterministic-version data directories
2. Run the deterministic generators listed in `DETERMINISTIC_BWC_VERSIONS`
3. Replace metadata entries for regenerated versions while preserving frozen entries

Or run individual generators:
```bash
make generate-backward-compatibility-v0.11.0
make generate-backward-compatibility-v0.11.1
make generate-backward-compatibility-v0.14.0
```

⚠️ **Important**: When running individual generators, they will append to existing metadata. Always clean first with `make clean-backward-compatibility-data` to avoid duplicates.
⚠️ **Important**: Frozen generator crates can still be run directly for historical investigation, but their output may be non-deterministic and should not be committed.

## Best Practices

Expand All @@ -180,7 +175,7 @@ make generate-backward-compatibility-v0.11.1
5. **Test after adding** - verify both generation and loading work
6. **Update this document** - keep the compatibility matrix current
7. **Version the generator crate** - set the crate version to match the KMS version exactly (e.g., `generate-v0.11.0` should be version `0.11.0`)
8. **Use `make generate-backward-compatibility-all`** - ensures proper metadata merging
8. **Use `make generate-backward-compatibility-all`** - refreshes deterministic data while preserving frozen entries

## Troubleshooting

Expand Down
25 changes: 18 additions & 7 deletions backward-compatibility/generate-v0.14.0/src/generate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

use std::{
borrow::Cow,
collections::HashSet,
fs,
path::{Path, PathBuf},
};
Expand All @@ -15,7 +16,7 @@ use backward_compatibility::{
ClassicPBSParametersTest, DKGParamsRegularTest, DKGParamsSnSTest,
SwitchAndSquashCompressionParametersTest, SwitchAndSquashParametersTest,
},
TestMetadataDD, TestMetadataKMS, TestMetadataKmsGrpc,
Testcase, TestMetadataDD, TestMetadataKMS, TestMetadataKmsGrpc,
};

// Parameters set for tests in kms-core 0.9, found in `PARAMS_TEST_BK_SNS`. However, for stability
Expand Down Expand Up @@ -115,9 +116,9 @@ macro_rules! define_store_versioned_auxiliary_fn {
}
define_store_versioned_auxiliary_fn!(store_versioned_auxiliary_05, Versionize_0_7);

pub fn store_metadata<Meta, P>(new_data: &Vec<Meta>, path: P)
pub fn store_metadata<T, P>(new_data: &Vec<Testcase<T>>, path: P)
where
Meta: Serialize + serde::de::DeserializeOwned + Clone,
T: Serialize + serde::de::DeserializeOwned + Clone,
P: AsRef<Path>,
{
let path = path.as_ref();
Expand All @@ -130,15 +131,25 @@ where
return;
}

// Load existing metadata
// Replace any existing entries for the versions being regenerated; leave
// every other version (notably the frozen ones) untouched. Without this,
// re-running the generator would append duplicate rows for the same
// version on every invocation.
let versions_being_written: HashSet<&str> = new_data
.iter()
.map(|t| t.kms_core_version_min.as_str())
.collect();

let existing_content = fs::read_to_string(path).unwrap();
let mut combined_data: Vec<Meta> =
let existing: Vec<Testcase<T>> =
ron::from_str(&existing_content).expect("Failed to deserialize existing metadata");

// Append new entries
let mut combined_data: Vec<Testcase<T>> = existing
.into_iter()
.filter(|t| !versions_being_written.contains(t.kms_core_version_min.as_str()))
.collect();
combined_data.extend_from_slice(new_data);

// Write combined data
let serialized =
ron::ser::to_string_pretty(&combined_data, ron::ser::PrettyConfig::default()).unwrap();
fs::write(path, serialized).unwrap();
Expand Down
18 changes: 13 additions & 5 deletions core/service/src/backup/custodian.rs
Original file line number Diff line number Diff line change
Expand Up @@ -376,14 +376,22 @@ impl Custodian {
})
}

// We allow the following lints because we are fine with mutating the rng even if
// we end up returning an error when signing the encrypted share.
#[allow(unknown_lints)]
#[allow(non_local_effect_before_error_return)]
pub fn generate_setup_message<R: Rng + CryptoRng>(
&self,
rng: &mut R,
custodian_name: String, // This is the human readable name of the custodian to be used in the setup message
) -> Result<InternalCustodianSetupMessage, BackupError> {
let timestamp = SystemTime::now().duration_since(UNIX_EPOCH)?.as_secs();
self.generate_setup_message_with_timestamp(rng, custodian_name, timestamp)
}

// The timestamp is taken as an explicit argument so that callers needing deterministic
// output (e.g. backward-compatibility data generators) can pass a fixed value.
pub fn generate_setup_message_with_timestamp<R: Rng + CryptoRng>(
&self,
rng: &mut R,
custodian_name: String,
timestamp: u64,
) -> Result<InternalCustodianSetupMessage, BackupError> {
Comment on lines +383 to 395
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really need both of these? Is generate_setup_message_with_timestamp really used separately from generate_setup_message? Maybe we can unify them into generate_setup_message and save ourselves some pub-API surface?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's a bit tricky, generate_setup_message_with_timestampbecause I wanted a "new" function that's deterministic, for the backward compatibility tests. but generate_setup_message is used everywhere else

let mut random_value = [0u8; 32];
rng.fill_bytes(&mut random_value);
Expand All @@ -392,7 +400,7 @@ impl Custodian {
header: HEADER.to_string(),
custodian_role: self.role,
random_value,
timestamp: SystemTime::now().duration_since(UNIX_EPOCH)?.as_secs(),
timestamp,
public_enc_key: self.enc_key.clone(),
public_verf_key: self.verification_key().clone(),
name: custodian_name,
Expand Down
Loading
Loading