mirror of
https://github.com/tlsnotary/tlsn.git
synced 2026-01-09 21:38:00 -05:00
Update C6 (#110)
* rename input mask to plaintext * update naming and docs for c6 * touch ups
This commit is contained in:
@@ -4,120 +4,106 @@ use mpc_circuits::{
|
||||
|
||||
/// TLS stage 6
|
||||
///
|
||||
/// Compute AES-CTR
|
||||
/// Encrypt plaintext or decrypt ciphertext in AES-CTR mode
|
||||
///
|
||||
/// T_IN could also just be used as a mask for the encrypted counter-block.
|
||||
///
|
||||
/// Inputs:
|
||||
///
|
||||
/// 0. N_CWK: 16-byte Notary share of client write-key
|
||||
/// 1. N_CIV: 4-byte Notary share of client IV
|
||||
/// 2. U_CWK: 16-byte User share of client write-key
|
||||
/// 3. U_CIV: 4-byte User share of client IV
|
||||
/// 4. U_MASK: 16-byte User mask for encrypted counter block
|
||||
/// 5. NONCE: U16 Nonce
|
||||
/// 6. CTR: U16 CTR
|
||||
/// 0. N_K: 16-byte Notary share of write-key
|
||||
/// 1. N_IV: 4-byte Notary share of IV
|
||||
/// 2. U_K: 16-byte User share of write-key
|
||||
/// 3. U_IV: 4-byte User share of IV
|
||||
/// 4. T_IN: 16-byte text (plaintext or ciphertext)
|
||||
/// 5. NONCE: 8-byte Explicit Nonce
|
||||
/// 6. CTR: U32 Counter
|
||||
///
|
||||
/// Outputs:
|
||||
///
|
||||
/// 0. MASKED_ECTR: 16-byte masked (U_MASK) encrypted counter block
|
||||
/// 0. T_OUT: 16-byte output (plaintext or ciphertext)
|
||||
pub fn c6() -> Circuit {
|
||||
let mut builder = CircuitBuilder::new("c6", "0.1.0");
|
||||
|
||||
let n_cwk = builder.add_input(
|
||||
"N_CWK",
|
||||
"16-byte Notary client write-key share",
|
||||
let n_k = builder.add_input(
|
||||
"N_K",
|
||||
"16-byte Notary write-key share",
|
||||
ValueType::Bytes,
|
||||
128,
|
||||
);
|
||||
let n_civ = builder.add_input(
|
||||
"N_SIV",
|
||||
"4-byte Notary share of client IV",
|
||||
ValueType::Bytes,
|
||||
32,
|
||||
);
|
||||
let u_cwk = builder.add_input(
|
||||
let n_iv = builder.add_input("N_SIV", "4-byte Notary share of IV", ValueType::Bytes, 32);
|
||||
let c_k = builder.add_input(
|
||||
"U_SWK",
|
||||
"16-byte User share of client write-key",
|
||||
"16-byte User share of write-key",
|
||||
ValueType::Bytes,
|
||||
128,
|
||||
);
|
||||
let u_civ = builder.add_input(
|
||||
"U_SIV",
|
||||
"4-byte User share of client IV",
|
||||
ValueType::Bytes,
|
||||
32,
|
||||
);
|
||||
let u_mask = builder.add_input(
|
||||
"U_MASK",
|
||||
"16-byte User mask for encrypted counter block",
|
||||
let c_iv = builder.add_input("U_SIV", "4-byte User share of IV", ValueType::Bytes, 32);
|
||||
let t_in = builder.add_input(
|
||||
"T_IN",
|
||||
"16-byte text (plaintext or ciphertext)",
|
||||
ValueType::Bytes,
|
||||
128,
|
||||
);
|
||||
let nonce = builder.add_input("NONCE", "U64 Nonce", ValueType::U64, 64);
|
||||
let ctr = builder.add_input("CTR", "U32 CTR", ValueType::U32, 32);
|
||||
let nonce = builder.add_input("NONCE", "8-byte Explicit Nonce", ValueType::Bytes, 64);
|
||||
let ctr = builder.add_input("CTR", "U32 Counter", ValueType::U32, 32);
|
||||
|
||||
let mut builder = builder.build_inputs();
|
||||
|
||||
let aes = Circuit::load_bytes(AES_128_REVERSE).expect("failed to load aes_128_reverse circuit");
|
||||
|
||||
let aes_ectr = builder.add_circ(aes);
|
||||
let cwk = builder.add_circ(nbit_xor(128));
|
||||
let civ = builder.add_circ(nbit_xor(32));
|
||||
let masked_ectr = builder.add_circ(nbit_xor(128));
|
||||
let k = builder.add_circ(nbit_xor(128));
|
||||
let iv = builder.add_circ(nbit_xor(32));
|
||||
let t_out = builder.add_circ(nbit_xor(128));
|
||||
|
||||
// cwk
|
||||
builder.connect(
|
||||
&n_cwk[..],
|
||||
&cwk.input(0).expect("nbit_xor missing input 0")[..],
|
||||
);
|
||||
builder.connect(
|
||||
&u_cwk[..],
|
||||
&cwk.input(1).expect("nbit_xor missing input 1")[..],
|
||||
);
|
||||
let cwk = cwk.output(0).expect("nbit_xor missing output 0");
|
||||
// Compute write-key
|
||||
builder.connect(&n_k[..], &k.input(0).expect("nbit_xor missing input 0")[..]);
|
||||
builder.connect(&c_k[..], &k.input(1).expect("nbit_xor missing input 1")[..]);
|
||||
let k = k.output(0).expect("nbit_xor missing output 0");
|
||||
|
||||
// civ
|
||||
// iv
|
||||
builder.connect(
|
||||
&n_civ[..],
|
||||
&civ.input(0).expect("nbit_xor missing input 0")[..],
|
||||
&n_iv[..],
|
||||
&iv.input(0).expect("nbit_xor missing input 0")[..],
|
||||
);
|
||||
builder.connect(
|
||||
&u_civ[..],
|
||||
&civ.input(1).expect("nbit_xor missing input 1")[..],
|
||||
&c_iv[..],
|
||||
&iv.input(1).expect("nbit_xor missing input 1")[..],
|
||||
);
|
||||
let civ = civ.output(0).expect("nbit_xor missing output 0");
|
||||
let iv = iv.output(0).expect("nbit_xor missing output 0");
|
||||
|
||||
// Compute ECTR
|
||||
builder.connect(
|
||||
&cwk[..],
|
||||
&aes_ectr.input(0).expect("aes missing input 0")[..],
|
||||
);
|
||||
// Compute encrypted counter-block
|
||||
builder.connect(&k[..], &aes_ectr.input(0).expect("aes missing input 0")[..]);
|
||||
let aes_ectr_m = aes_ectr.input(1).expect("aes missing input 1");
|
||||
builder.connect(&civ[..], &aes_ectr_m[96..]);
|
||||
// Implicit nonce
|
||||
builder.connect(&iv[..], &aes_ectr_m[96..]);
|
||||
// Explicit nonce
|
||||
builder.connect(&nonce[..], &aes_ectr_m[32..96]);
|
||||
// Counter
|
||||
builder.connect(&ctr[..], &aes_ectr_m[..32]);
|
||||
let ectr = aes_ectr.output(0).expect("aes missing output 0");
|
||||
|
||||
// Apply ECTR mask
|
||||
// Apply text
|
||||
builder.connect(
|
||||
&ectr[..],
|
||||
&masked_ectr.input(0).expect("nbit_xor missing input 0")[..],
|
||||
&t_out.input(0).expect("nbit_xor missing input 0")[..],
|
||||
);
|
||||
builder.connect(
|
||||
&u_mask[..],
|
||||
&masked_ectr.input(1).expect("nbit_xor missing input 1")[..],
|
||||
&t_in[..],
|
||||
&t_out.input(1).expect("nbit_xor missing input 1")[..],
|
||||
);
|
||||
|
||||
let mut builder = builder.build_gates();
|
||||
|
||||
let out_ectr = builder.add_output(
|
||||
"MASKED_ECTR",
|
||||
"16-byte masked (U_MASK) encrypted counter block",
|
||||
"T_OUT",
|
||||
"16-byte output (plaintext or ciphertext)",
|
||||
ValueType::Bytes,
|
||||
128,
|
||||
);
|
||||
|
||||
builder.connect(
|
||||
&masked_ectr.output(0).expect("nbit_xor missing output 0")[..],
|
||||
&t_out.output(0).expect("nbit_xor missing output 0")[..],
|
||||
&out_ectr[..],
|
||||
);
|
||||
|
||||
@@ -140,58 +126,53 @@ mod tests {
|
||||
|
||||
let mut rng = thread_rng();
|
||||
|
||||
let n_cwk: [u8; 16] = rng.gen();
|
||||
let n_civ: [u8; 4] = rng.gen();
|
||||
let u_cwk: [u8; 16] = rng.gen();
|
||||
let u_civ: [u8; 4] = rng.gen();
|
||||
let u_mask: [u8; 16] = rng.gen();
|
||||
let nonce: u64 = rng.gen();
|
||||
let n_k: [u8; 16] = rng.gen();
|
||||
let n_iv: [u8; 4] = rng.gen();
|
||||
let u_k: [u8; 16] = rng.gen();
|
||||
let u_iv: [u8; 4] = rng.gen();
|
||||
let t_in: [u8; 16] = rng.gen();
|
||||
let explicit_nonce: [u8; 8] = rng.gen();
|
||||
let ctr: u32 = rng.gen();
|
||||
|
||||
// combine key shares
|
||||
let cwk = n_cwk
|
||||
let k = n_k.iter().zip(u_k).map(|(n, u)| n ^ u).collect::<Vec<u8>>();
|
||||
let iv = n_iv
|
||||
.iter()
|
||||
.zip(u_cwk)
|
||||
.map(|(n, u)| n ^ u)
|
||||
.collect::<Vec<u8>>();
|
||||
let civ = n_civ
|
||||
.iter()
|
||||
.zip(u_civ)
|
||||
.zip(u_iv)
|
||||
.map(|(n, u)| n ^ u)
|
||||
.collect::<Vec<u8>>();
|
||||
|
||||
// set AES key
|
||||
let key = GenericArray::clone_from_slice(&cwk);
|
||||
let key = GenericArray::clone_from_slice(&k);
|
||||
let cipher = Aes128::new(&key);
|
||||
|
||||
// AES-ECB encrypt a block with counter and nonce
|
||||
let mut msg = [0u8; 16];
|
||||
msg[0..4].copy_from_slice(&civ);
|
||||
msg[4..12].copy_from_slice(&nonce.to_be_bytes());
|
||||
msg[0..4].copy_from_slice(&iv);
|
||||
msg[4..12].copy_from_slice(&explicit_nonce);
|
||||
msg[12..16].copy_from_slice(&ctr.to_be_bytes());
|
||||
let mut msg = GenericArray::clone_from_slice(&msg);
|
||||
cipher.encrypt_block(&mut msg);
|
||||
let ectr = msg;
|
||||
|
||||
// XOR the first block and verify_data with User's mask
|
||||
let ectr_masked = ectr
|
||||
let t_out = ectr
|
||||
.iter()
|
||||
.zip(u_mask)
|
||||
.zip(t_in)
|
||||
.map(|(v, u)| v ^ u)
|
||||
.collect::<Vec<u8>>();
|
||||
|
||||
test_circ(
|
||||
&circ,
|
||||
&[
|
||||
Value::Bytes(n_cwk.into_iter().rev().collect()),
|
||||
Value::Bytes(n_civ.into_iter().rev().collect()),
|
||||
Value::Bytes(u_cwk.into_iter().rev().collect()),
|
||||
Value::Bytes(u_civ.into_iter().rev().collect()),
|
||||
Value::Bytes(u_mask.into_iter().rev().collect()),
|
||||
Value::U64(nonce),
|
||||
Value::Bytes(n_k.into_iter().rev().collect()),
|
||||
Value::Bytes(n_iv.into_iter().rev().collect()),
|
||||
Value::Bytes(u_k.into_iter().rev().collect()),
|
||||
Value::Bytes(u_iv.into_iter().rev().collect()),
|
||||
Value::Bytes(t_in.into_iter().rev().collect()),
|
||||
Value::Bytes(explicit_nonce.into_iter().rev().collect()),
|
||||
Value::U32(ctr),
|
||||
],
|
||||
&[Value::Bytes(ectr_masked.into_iter().rev().collect())],
|
||||
&[Value::Bytes(t_out.into_iter().rev().collect())],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user