Skip to main content

confium_privacy/
oblivious_transfer.rs

1//! Oblivious Transfer (OT).
2//!
3//! 1-out-of-2 OT: the sender has two messages (m0, m1), the receiver
4//! gets exactly one (m_b) without the sender learning which, and the
5//! receiver doesn't learn the other message.
6//!
7//! Based on the Bellare-Micali protocol using P-256.
8
9use 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/// Sender's setup message.
17#[derive(Debug, Clone)]
18pub struct OtSetup {
19    /// Random point C.
20    pub c: AffinePoint,
21}
22
23/// Receiver's choice message.
24#[derive(Debug, Clone)]
25pub struct OtChoice {
26    /// Point P_b sent to sender.
27    pub p: AffinePoint,
28}
29
30/// Sender's encrypted messages.
31#[derive(Debug, Clone)]
32pub struct OtEncrypted {
33    pub e0: Vec<u8>,
34    pub e1: Vec<u8>,
35}
36
37/// Receiver's output for choice bit b.
38#[derive(Debug, Clone)]
39pub struct OtReceiver {
40    /// Choice bit.
41    pub b: bool,
42    /// Secret scalar used to decrypt.
43    pub k: Scalar,
44}
45
46/// Phase 1: Sender initiates with a random point.
47pub 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
53/// Phase 2: Receiver chooses bit b and generates choice message.
54pub 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    // If b == 0: P = k*G
59    // If b == 1: P = k*G + C
60    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
69/// Phase 3: Sender encrypts both messages.
70pub fn sender_encrypt(choice: &OtChoice, setup: &OtSetup, m0: &[u8], m1: &[u8]) -> OtEncrypted {
71    // k0 = P, k1 = P - C
72    // Derive encryption keys from points
73    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
82/// Phase 4: Receiver decrypts the chosen message.
83pub 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        // The sender sees P which is different for b=0 and b=1
137        // but without knowing k, cannot determine b
138        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        // Receiver can only decrypt e0 (their choice)
149        let decrypted = receiver_decrypt(&enc, &receiver);
150        assert_eq!(decrypted, m0);
151        // e1 would decrypt to garbage with k0's key
152    }
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}