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
#![allow(dead_code)] use sinkhole_core::errors::QueryError; use curve25519_dalek::constants::RISTRETTO_BASEPOINT_TABLE; use curve25519_dalek::scalar::Scalar; use elgamal_ristretto::ciphertext::Ciphertext; use elgamal_ristretto::private::SecretKey; use elgamal_ristretto::public::PublicKey; #[derive(Debug, Clone)] pub struct Query { pub encrypted: Vec<Ciphertext>, private_key: SecretKey, size: usize, } impl Query { pub fn new(sk: SecretKey, size: usize, index: usize) -> Result<Self, QueryError> { if index > size - 1 { return Err(QueryError { error: "Index of query should not be larger than the size of the query".to_owned(), }); } let pk = PublicKey::from(&sk); let mut decrypted_query = vec![Scalar::zero(); size - 1]; decrypted_query.insert(index, Scalar::one()); let encrypted_query: Vec<Ciphertext> = decrypted_query .into_iter() .map(|x| pk.encrypt(&(&x * &RISTRETTO_BASEPOINT_TABLE))) .collect(); Ok(Query { private_key: sk, size, encrypted: encrypted_query, }) } } impl sinkhole_core::traits::core::Query for Query { fn extract_result(&self, result: Ciphertext, k: u32) -> Result<Scalar, QueryError> { let point_result = self.private_key.decrypt(&result); recover_scalar(point_result, k) } } fn recover_scalar( point: curve25519_dalek::ristretto::RistrettoPoint, k: u32, ) -> Result<Scalar, QueryError> { for i in 0..2u64.pow(k) { if &Scalar::from(i as u64) * &RISTRETTO_BASEPOINT_TABLE == point { return Ok(Scalar::from(i as u64)); } } Err(QueryError { error: format!["Scalar is not in [0..2^{}] range", k], }) }