1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
use rand_core::OsRng;
use curve25519_dalek::scalar::Scalar;

/// The byte length of a scalar.
pub const SCALAR_SIZE: usize = 32;
/// The byte length of a point.
pub const POINT_SIZE : usize = 32;
/// The byte length of a ciphertext.
pub const CIPHER_SIZE: usize = 2 * POINT_SIZE;
/// log_2(DEFAULT_MMAX).
pub const DEFAULT_MMAX_MOD: u8 = 24;
/// The maximum number of entries in `mG.bin`.
pub const DEFAULT_MMAX: u32 = 1 << DEFAULT_MMAX_MOD;
/// The default data directory name.
pub const DEFAULT_DATA_DIR: &str = ".EllipticPIR";

/// The default path to mG.bin.
pub fn mg_default_path() -> Result<String, std::env::VarError> {
    Ok(std::env::var("HOME")? + "/" + DEFAULT_DATA_DIR + "/mG.bin")
}

pub mod ecelgamal;
pub mod selector;
pub mod reply;

pub trait Rng {
    fn next(&mut self) -> Scalar;
}

#[derive(Default)]
pub struct DefaultRng {
    csprng: OsRng,
}

impl Rng for DefaultRng {
    fn next(&mut self) -> Scalar {
        Scalar::random(&mut self.csprng)
    }
}

pub struct ConstRng {
    scalars: Vec<Scalar>,
    index: usize,
}
impl ConstRng {
    pub fn new(scalars: Vec<Scalar>) -> Self {
        Self {
            scalars,
            index: 0,
        }
    }
}
impl Rng for ConstRng {
    fn next(&mut self) -> Scalar {
        self.index += 1;
        self.scalars[self.index - 1]
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::ecelgamal::*;
    use sha2::{Digest, Sha256};
    pub const PRIVKEY: [u8; SCALAR_SIZE] = [
        0x7e, 0xf6, 0xad, 0xd2, 0xbe, 0xd5, 0x9a, 0x79,
        0xba, 0x6e, 0xdc, 0xfb, 0xa4, 0x8f, 0xde, 0x7a,
        0x55, 0x31, 0x75, 0x4a, 0xf5, 0x93, 0x76, 0x34,
        0x6c, 0x8b, 0x52, 0x84, 0xee, 0xf2, 0x52, 0x07,
    ];
    pub const PRIVKEY_STR: &str = "7ef6add2bed59a79ba6edcfba48fde7a5531754af59376346c8b5284eef25207";
    pub const PUBKEY: [u8; POINT_SIZE] = [
        0x9c, 0x76, 0x82, 0x3d, 0xbd, 0xb9, 0xbf, 0x04,
        0x8f, 0xc5, 0xc2, 0xaf, 0x00, 0x0e, 0x28, 0xa1,
        0x48, 0xee, 0x02, 0x19, 0x99, 0xfb, 0x7f, 0x21,
        0xca, 0x1f, 0x84, 0xb8, 0xfe, 0x73, 0xd7, 0xe8,
    ];
    pub const PUBKEY_STR: &str = "9c76823dbdb9bf048fc5c2af000e28a148ee021999fb7f21ca1f84b8fe73d7e8";
    pub static mut DEC_CTX: Option<DecryptionContext> = None;
    static DEC_CTX_INIT: std::sync::Once = std::sync::Once::new();
    pub fn init_dec_ctx() {
        unsafe {
            DEC_CTX_INIT.call_once(|| {
                DEC_CTX = Some(DecryptionContext::load_from_file(None).unwrap());
            });
        }
    }
    pub fn sha256sum(buf: &Vec<u8>) -> [u8; 32] {
        Sha256::digest(buf).into()
    }
    pub struct XorShift {
        x: u32,
        y: u32,
        z: u32,
        w: u32,
    }
    impl Default for XorShift {
        fn default() -> Self {
            Self {
                x: 123456789,
                y: 362436069,
                z: 521288629,
                w: 88675123,
            }
        }
    }
    impl XorShift {
        pub fn next(&mut self) -> u32 {
            let t = self.x ^ (self.x << 11);
            self.x = self.y; self.y = self.z; self.z = self.w;
            self.w = (self.w ^ (self.w >> 19)) ^ (t ^ (t >> 8));
            self.w
        }
    }
    #[derive(Default)]
    pub struct XorShiftRng {
        xorshift: XorShift,
    }
    impl Rng for XorShiftRng {
        fn next(&mut self) -> Scalar {
            let mut buf = [0u8; 32];
            for i in 0..32 {
                buf[i] = (self.xorshift.next() & 0xff) as u8;
            }
            buf[31] &= 0x1fu8;
            Scalar::from_bits(buf)
        }
    }
}