Skip to content

Commit 942afb2

Browse files
authored
feat: CRP-2958 Add support for offline derivation of PocketIC keys to ic_vetkeys crate (#250)
1 parent 0c241b8 commit 942afb2

File tree

3 files changed

+62
-4
lines changed

3 files changed

+62
-4
lines changed

backend/rs/ic_vetkeys/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
## [0.6.0] - Not Yet Released
44

5+
### Added
6+
7+
- Added support for offline generation of keys relative to the PocketIC master keys, similar to the existing functionality for offline derivation relative to the production master public keys.
8+
59
### Changed
610

711
- Changes to format of the AES-GCM encryption helpers added in 0.5.0. This version can decrypt messages encrypted by 0.5.0, but 0.5.0 cannot decrypt messages encrypted by 0.6.0

backend/rs/ic_vetkeys/src/utils/mod.rs

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,25 @@ const MASTER_PUBLIC_KEY_BYTES_KEY_1 : [u8; 96] = hex!("a9caf9ae8af0c7c7272f8a122
2222

2323
const MASTER_PUBLIC_KEY_BYTES_TEST_KEY_1 : [u8; 96] = hex!("ad86e8ff845912f022a0838a502d763fdea547c9948f8cb20ea7738dd52c1c38dcb4c6ca9ac29f9ac690fc5ad7681cb41922b8dffbd65d94bff141f5fb5b6624eccc03bf850f222052df888cf9b1e47203556d7522271cbb879b2ef4b8c2bfb1");
2424

25+
const POCKETIC_MASTER_PUBLIC_KEY_BYTES_KEY_1 : [u8; 96] = hex!("8c800b5cff00463d26e8167369168827f1e48f4d8d60f71dd6a295580f65275b5f5f8e6a792c876b2c72492136530d0710a27522ee63977a76216c3cef9e70bfcb45b88736fc62142e7e0737848ce06cbb1f45a4a6a349b142ae5cf7853561e0");
26+
27+
const POCKETIC_MASTER_PUBLIC_KEY_BYTES_TEST_KEY_1 : [u8; 96] = hex!("9069b82c7aae418cef27678291e7f2cb1a008a500eceba7199bffca12421b07c158987c6a22618af3d1958738b2835691028801f7663d311799733286c557c8979184bb62cb559a4d582fca7d2e48b860f08ed6641aef66a059ec891889a6218");
28+
29+
const POCKETIC_MASTER_PUBLIC_KEY_BYTES_DFX_TEST_KEY : [u8; 96] = hex!("b181c14cf9d04ba45d782c0067a44b0aaa9fc2acf94f1a875f0dae801af4f80339a7e6bf8b09fcf993824c8df3080b3f1409b688ca08cbd44d2cb28db9899f4aa3b5f06b9174240448e10be2f01f9f80079ea5431ce2d11d1c8d1c775333315f");
30+
31+
fn decode_g2_mpk(bytes: &[u8; 96]) -> G2Affine {
32+
G2Affine::from_compressed(bytes).expect("Hardcoded master public key not a valid point")
33+
}
34+
2535
lazy_static::lazy_static! {
2636
static ref G2PREPARED_NEG_G : G2Prepared = G2Affine::generator().neg().into();
2737

28-
static ref G2_KEY_1: G2Affine = G2Affine::from_compressed(&MASTER_PUBLIC_KEY_BYTES_KEY_1).expect("Hardcoded master public key not a valid point");
29-
static ref G2_TEST_KEY_1: G2Affine = G2Affine::from_compressed(&MASTER_PUBLIC_KEY_BYTES_TEST_KEY_1).expect("Hardcoded master public key not a valid point");
38+
static ref PROD_G2_KEY_1: G2Affine = decode_g2_mpk(&MASTER_PUBLIC_KEY_BYTES_KEY_1);
39+
static ref PROD_G2_TEST_KEY_1: G2Affine = decode_g2_mpk(&MASTER_PUBLIC_KEY_BYTES_TEST_KEY_1);
40+
41+
static ref POCKETIC_G2_KEY_1: G2Affine = decode_g2_mpk(&POCKETIC_MASTER_PUBLIC_KEY_BYTES_KEY_1);
42+
static ref POCKETIC_G2_TEST_KEY_1: G2Affine = decode_g2_mpk(&POCKETIC_MASTER_PUBLIC_KEY_BYTES_TEST_KEY_1);
43+
static ref POCKETIC_G2_DFX_TEST_KEY: G2Affine = decode_g2_mpk(&POCKETIC_MASTER_PUBLIC_KEY_BYTES_DFX_TEST_KEY);
3044
}
3145

3246
const G1AFFINE_BYTES: usize = 48; // Size of compressed form
@@ -396,8 +410,22 @@ impl MasterPublicKey {
396410
/// Returns None if the provided key_id is not known
397411
pub fn for_mainnet_key(key_id: &VetKDKeyId) -> Option<Self> {
398412
match (key_id.curve, key_id.name.as_str()) {
399-
(VetKDCurve::Bls12_381_G2, "key_1") => Some(Self::new(*G2_KEY_1)),
400-
(VetKDCurve::Bls12_381_G2, "test_key_1") => Some(Self::new(*G2_TEST_KEY_1)),
413+
(VetKDCurve::Bls12_381_G2, "key_1") => Some(Self::new(*PROD_G2_KEY_1)),
414+
(VetKDCurve::Bls12_381_G2, "test_key_1") => Some(Self::new(*PROD_G2_TEST_KEY_1)),
415+
(_, _) => None,
416+
}
417+
}
418+
419+
/// Return the hardcoded master public key used for testing in PocketIC
420+
///
421+
/// Returns None if the provided key_id is not known
422+
pub fn for_pocketic_key(key_id: &VetKDKeyId) -> Option<Self> {
423+
match (key_id.curve, key_id.name.as_str()) {
424+
(VetKDCurve::Bls12_381_G2, "key_1") => Some(Self::new(*POCKETIC_G2_KEY_1)),
425+
(VetKDCurve::Bls12_381_G2, "test_key_1") => Some(Self::new(*POCKETIC_G2_TEST_KEY_1)),
426+
(VetKDCurve::Bls12_381_G2, "dfx_test_key") => {
427+
Some(Self::new(*POCKETIC_G2_DFX_TEST_KEY))
428+
}
401429
(_, _) => None,
402430
}
403431
}

backend/rs/ic_vetkeys/tests/utils.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,32 @@ fn test_derivation_using_production_key() {
135135
);
136136
}
137137

138+
#[test]
139+
fn test_derivation_using_pocketic_keys() {
140+
let test_vectors = [
141+
("key_1", "899a951f6ec2f9a96759c554a6cb01fb1cb20b2f2f96a2d2c869221c04d3349c3be8d49c3257312aed031f430f15f7ef0f4d43adf11251015d70dd91ac07df50fb70818ece721a1d6a314204acddde55542902f5d0d95e2406a5ab1fad18349d"),
142+
("test_key_1", "a60993fc46593728bd9b0a4ffb1fb9a662dd89b29c99fde36e403c311c8992e6eeb097b31174dd43f74e73fe10c190271193a4345490f64a41ce778a2f6e7c16804919e843ac72ff65bab959c53fa839c9fb3cb263e41498d17fb82704fe18bc"),
143+
("dfx_test_key", "800424bea66b95b715f86a9bed06b1f60df98206a57235c3e0f2da4d485dc1c93c56eef54155d559ef45c757fb0444920620b932652f1d683fdbc57db98b5aeb8ba664a5e040cbdf4d685e4e236a7193d1bd5b0927204fab05fff4f61f26b358"),
144+
];
145+
146+
let canister_id = candid::Principal::from_text("uzt4z-lp777-77774-qaabq-cai").unwrap();
147+
148+
for (key_id, expected) in &test_vectors {
149+
let context = format!("Test Derivation For PocketIC VetKD {}", key_id);
150+
151+
let key_id = VetKDKeyId {
152+
curve: VetKDCurve::Bls12_381_G2,
153+
name: key_id.to_string(),
154+
};
155+
156+
let mk = MasterPublicKey::for_pocketic_key(&key_id).unwrap();
157+
let canister_key = mk.derive_canister_key(canister_id.as_slice());
158+
let derived_key = canister_key.derive_sub_key(context.as_bytes());
159+
160+
assert_eq!(hex::encode(derived_key.serialize()), *expected);
161+
}
162+
}
163+
138164
#[test]
139165
fn test_second_level_public_key_derivation() {
140166
let canister_key = DerivedPublicKey::deserialize(&hex::decode("8bf165ea580742abf5fd5123eb848aa116dcf75c3ddb3cd3540c852cf99f0c5394e72dfc2f25dbcb5f9220f251cd04040a508a0bcb8b2543908d6626b46f09d614c924c5deb63a9949338ae4f4ac436bd77f8d0a392fd29de0f392a009fa61f3").unwrap()).unwrap();

0 commit comments

Comments
 (0)