Proxy Re-Encryption — Allowing Alice To Share Her Protect Secret Key With Bob

Let’s say that Alice has stored an encrypted file, and which uses a given key (K_A). Alice can then protect her key by encrypting the key…

Proxy Re-Encryption — Allowing Alice To Share Her Protect Secret Key With Bob

Let’s say that Alice has stored an encrypted file, which uses a given key (K_A). Alice can then protect her key by encrypting the key with her public key. She can then decrypt this encrypted key with her private key (E_pk(K_A)):

But let’s say that Alice now wants to share the encrypted document with Bob, and where we want to convert the key encrypted with Alice’s public key, into one that can be decrypted by Bob’s private key. For this, we can use transform (or proxy) re-encryption. At the core of this is a transform key, which is the key which can decrypt the protected key to Bob’s private one. This is done by Trent, who is trusted to take Alice’s private key and Bob’s public key, and create a transform key (T_AB). This can then be given to Bob when required, along with Alice’s protected encryption key:

In this case, Trent can become the proxy and trust create the transformation key, and receive Bob’s public key, and Alice’s private key. So let’s code using Rust (as it is a highly secure programming environment, with lots of libraries — crates). First, we create the project with:

cargo new transform

We then go into the transform folder and add the following to the cargo.toml file:

[package]
name = "pr"
version = "0.1.0"
authors = ["billbuchanan "]
edition = "2018"
[dependencies]
recrypt = "0.11.0"
hex = "0.4.2"
pad = "0.1"

Next, we go into the src folder, and edit the main.rs file with [here]:

use recrypt::prelude::*;
use recrypt::api::Plaintext;
use pad::PadStr;
use std::env;

fn main() {

fn unsize
(x: &[T]) -> &[T] { x }
// create a new recrypt
let recrypt = Recrypt::new();

let mut mystr="Hello";


let args: Vec<String> = env::args().collect();

if args.len() >1 { mystr = &args[1];}



let x=Plaintext::new_from_slice(mystr.pad_to_width_with_char(384,' ').as_bytes());

let pt = x.unwrap();

let signing_keypair= recrypt.generate_ed25519_key_pair();



let (initial_priv_key, initial_pub_key) = recrypt.generate_key_pair().unwrap();

let encrypted_val = recrypt.encrypt(&pt, &initial_pub_key, &signing_keypair).unwrap();


let (target_priv_key, target_pub_key) = recrypt.generate_key_pair().unwrap();


let initial_to_target_transform_key = recrypt.generate_transform_key(
&initial_priv_key,
&target_pub_key,
&signing_keypair).unwrap();


let transformed_val = recrypt.transform(
encrypted_val,
initial_to_target_transform_key,
&signing_keypair).unwrap();


let decrypted_val = recrypt.decrypt(transformed_val, &target_priv_key).unwrap();


println!("\nInput string:\t{} ",mystr);
println!("\nSigning key:\t{} ",hex::encode(unsize(signing_keypair.bytes())));
println!("\nInitial Private key:\t{} ",hex::encode(unsize(initial_priv_key.bytes())));
let (x,y)=initial_pub_key.bytes_x_y();
println!("\nInitial Public key:\t{},{} ",hex::encode(unsize(x)),hex::encode(unsize(y)) );
println!("\nTarget Private key:\t{} ",hex::encode(unsize(target_priv_key.bytes())));
let (x,y)=target_pub_key.bytes_x_y();
println!("\nTarget Public key:\t{},{} ",hex::encode(unsize(x)),hex::encode(unsize(y)) );


println!("\nDecrypted:\t{} ",String::from_utf8_lossy(decrypted_val.bytes()));



}

Finally, we simply build with:

cargo build

A sample run is [here]:

Input string:	Hello 

Signing key: c56c504099f144f04a983ae7d2d63371f4dafc8d81692cf495027620a830d36782c92cd95e9b4cbe1f3bcfbd0503d5cc7cec4017c69f7291482e219baac62bb3

Initial Private key: 142eaf727c19dc3f5739872c58b2497f325e72ecfca595b2b0e522a6686122e5

Initial Public key: 705c10bc00660834d4158d8e12f3454b40e71842f9005588cfe2b31452e937b7,679bc54986c77f3bae8e8b9a25f076d251474c0657f5a2f9ce5f75a4f3777e96

Target Private key: 41417931a29d6facc9a8ca912c706d4d02f649fbe4fd1c5e076960981df45b04

Target Public key: 64269f853892b302f8645ac51a8fda719d464b59a889d104c11e927d6175237f,59dabe12de1f8f347903a0737b83e766fe78fe00f51a832a148647e5a716ba0d

Decrypted: Hello

Conclusions

With transform encryption — also known as proxy re-encryption — we are able to share Alice’s protected key with Bob, but only through a trusted proxy.