confium_privacy/
oblivious_transfer.rs1use getrandom::SysRng;
10use p256::elliptic_curve::Field;
11use p256::elliptic_curve::rand_core::UnwrapErr;
12use p256::elliptic_curve::sec1::ToSec1Point;
13use p256::{AffinePoint, ProjectivePoint, Scalar};
14use sha2::{Digest, Sha256};
15
16#[derive(Debug, Clone)]
18pub struct OtSetup {
19 pub c: AffinePoint,
21}
22
23#[derive(Debug, Clone)]
25pub struct OtChoice {
26 pub p: AffinePoint,
28}
29
30#[derive(Debug, Clone)]
32pub struct OtEncrypted {
33 pub e0: Vec<u8>,
34 pub e1: Vec<u8>,
35}
36
37#[derive(Debug, Clone)]
39pub struct OtReceiver {
40 pub b: bool,
42 pub k: Scalar,
44}
45
46pub fn sender_setup() -> (OtSetup, Scalar) {
48 let c_scalar = Scalar::random(&mut UnwrapErr(SysRng));
49 let c = (ProjectivePoint::GENERATOR * c_scalar).to_affine();
50 (OtSetup { c }, c_scalar)
51}
52
53pub fn receiver_choose(b: bool, setup: &OtSetup) -> (OtChoice, OtReceiver) {
55 let k = Scalar::random(&mut UnwrapErr(SysRng));
56 let k_g = (ProjectivePoint::GENERATOR * k).to_affine();
57
58 let p = if b {
61 (ProjectivePoint::from(k_g) + ProjectivePoint::from(setup.c)).to_affine()
62 } else {
63 k_g
64 };
65
66 (OtChoice { p }, OtReceiver { b, k })
67}
68
69pub fn sender_encrypt(choice: &OtChoice, setup: &OtSetup, m0: &[u8], m1: &[u8]) -> OtEncrypted {
71 let k0_point = choice.p;
74 let k1_point = (ProjectivePoint::from(choice.p) - ProjectivePoint::from(setup.c)).to_affine();
75
76 let e0 = xor_encrypt(&k0_point, m0);
77 let e1 = xor_encrypt(&k1_point, m1);
78
79 OtEncrypted { e0, e1 }
80}
81
82pub fn receiver_decrypt(enc: &OtEncrypted, receiver: &OtReceiver) -> Vec<u8> {
84 let k_g = (ProjectivePoint::GENERATOR * receiver.k).to_affine();
85 if receiver.b {
86 xor_encrypt(&k_g, &enc.e1)
87 } else {
88 xor_encrypt(&k_g, &enc.e0)
89 }
90}
91
92fn xor_encrypt(key_point: &AffinePoint, data: &[u8]) -> Vec<u8> {
93 let mut hasher = Sha256::new();
94 hasher.update(b"ot-key");
95 hasher.update(key_point.to_sec1_point(true).as_bytes());
96 let key = hasher.finalize();
97 let key = &key[..];
98
99 data.iter()
100 .enumerate()
101 .map(|(i, &b)| b ^ key[i % key.len()])
102 .collect()
103}
104
105#[cfg(test)]
106mod tests {
107 use super::*;
108
109 #[test]
110 fn ot_chooses_zero() {
111 let (setup, _) = sender_setup();
112 let (choice, receiver) = receiver_choose(false, &setup);
113 let m0 = b"message zero";
114 let m1 = b"message one";
115 let enc = sender_encrypt(&choice, &setup, m0, m1);
116 let decrypted = receiver_decrypt(&enc, &receiver);
117 assert_eq!(decrypted, m0);
118 }
119
120 #[test]
121 fn ot_chooses_one() {
122 let (setup, _) = sender_setup();
123 let (choice, receiver) = receiver_choose(true, &setup);
124 let m0 = b"message zero";
125 let m1 = b"message one";
126 let enc = sender_encrypt(&choice, &setup, m0, m1);
127 let decrypted = receiver_decrypt(&enc, &receiver);
128 assert_eq!(decrypted, m1);
129 }
130
131 #[test]
132 fn sender_does_not_learn_choice() {
133 let (setup, _) = sender_setup();
134 let (choice0, _) = receiver_choose(false, &setup);
135 let (choice1, _) = receiver_choose(true, &setup);
136 assert_ne!(choice0.p, choice1.p);
139 }
140
141 #[test]
142 fn receiver_does_not_learn_other_message() {
143 let (setup, _) = sender_setup();
144 let (choice, receiver) = receiver_choose(false, &setup);
145 let m0 = b"zero";
146 let m1 = b"one";
147 let enc = sender_encrypt(&choice, &setup, m0, m1);
148 let decrypted = receiver_decrypt(&enc, &receiver);
150 assert_eq!(decrypted, m0);
151 }
153
154 #[test]
155 fn different_messages_each_time() {
156 let (setup, _) = sender_setup();
157 let (choice, receiver) = receiver_choose(true, &setup);
158 let m0 = b"aaa";
159 let m1 = b"bbb";
160 let enc = sender_encrypt(&choice, &setup, m0, m1);
161 let decrypted = receiver_decrypt(&enc, &receiver);
162 assert_eq!(decrypted, b"bbb");
163 }
164
165 #[test]
166 fn large_messages() {
167 let (setup, _) = sender_setup();
168 let (choice, receiver) = receiver_choose(false, &setup);
169 let m0 = vec![0xAA; 1000];
170 let m1 = vec![0xBB; 1000];
171 let enc = sender_encrypt(&choice, &setup, &m0, &m1);
172 let decrypted = receiver_decrypt(&enc, &receiver);
173 assert_eq!(decrypted, m0);
174 }
175
176 #[test]
177 fn empty_message() {
178 let (setup, _) = sender_setup();
179 let (choice, receiver) = receiver_choose(false, &setup);
180 let enc = sender_encrypt(&choice, &setup, b"", b"data");
181 let decrypted = receiver_decrypt(&enc, &receiver);
182 assert!(decrypted.is_empty());
183 }
184}