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
// Copyright 2020 WeDPR Lab Project Authors. Licensed under Apache-2.0.

//! Common utility functions for ZKP.

use curve25519_dalek::constants::{
    RISTRETTO_BASEPOINT_COMPRESSED, RISTRETTO_BASEPOINT_POINT,
};

use curve25519_dalek::{
    ristretto::{CompressedRistretto, RistrettoPoint},
    scalar::Scalar,
};

#[macro_use]
extern crate wedpr_l_macros;
#[macro_use]
extern crate lazy_static;

mod config;
use config::HASH;
use rand::Rng;
use sha3::Sha3_512;
use std::convert::TryInto;
use wedpr_l_utils::{error::WedprError, traits::Hash};

lazy_static! {
    /// A base point used by various crypto algorithms.
    pub static ref BASEPOINT_G1: RistrettoPoint = RISTRETTO_BASEPOINT_POINT;
    /// Another base point used by various crypto algorithms.
    pub static ref BASEPOINT_G2: RistrettoPoint =
        RistrettoPoint::hash_from_bytes::<Sha3_512>(
            RISTRETTO_BASEPOINT_COMPRESSED.as_bytes()
        );
}

/// Serialized data size of a point.
const RISTRETTO_POINT_SIZE_IN_BYTES: usize = 32;

/// Gets a random Scalar.
pub fn get_random_scalar() -> Scalar {
    Scalar::random(&mut rand::thread_rng())
}

/// Converts an arbitrary string to Scalar.
/// It will hash it first, and transform the numeric value of hash output to
/// Scalar.
pub fn hash_to_scalar<T: ?Sized + AsRef<[u8]>>(input: &T) -> Scalar {
    let mut array = [0; 32];
    array.clone_from_slice(&HASH.hash(input));
    Scalar::from_bytes_mod_order(array)
}

/// Converts Scalar to a vector.
pub fn scalar_to_bytes(input: &Scalar) -> Vec<u8> {
    input.as_bytes().to_vec()
}

/// Converts Scalar to a slice.
pub fn scalar_to_slice(input: &Scalar) -> [u8; 32] {
    input.as_bytes().clone()
}

/// Extracts a slice of &[u8; 32] from the given slice.
fn to_bytes32_slice(barry: &[u8]) -> Result<&[u8; 32], WedprError> {
    let pop_u8 = match barry.try_into() {
        Ok(v) => v,
        Err(_) => return Err(WedprError::FormatError),
    };
    Ok(pop_u8)
}

// Private utility functions.

/// Converts a vector to Scalar.
pub fn bytes_to_scalar(input: &[u8]) -> Result<Scalar, WedprError> {
    let get_num_u8 = to_bytes32_slice(&input)?;
    let scalar_num = Scalar::from_bits(*get_num_u8);
    Ok(scalar_num)
}

/// Converts RistrettoPoint to a bytes vector.
pub fn point_to_bytes(point: &RistrettoPoint) -> Vec<u8> {
    point.compress().to_bytes().to_vec()
}

/// Converts RistrettoPoint to a bytes slice.
pub fn point_to_slice(point: &RistrettoPoint) -> [u8; 32] {
    point.compress().to_bytes()
}

/// Converts a vector to RistrettoPoint.
pub fn bytes_to_point(point: &[u8]) -> Result<RistrettoPoint, WedprError> {
    if point.len() != RISTRETTO_POINT_SIZE_IN_BYTES {
        wedpr_println!("bytes_to_point decode failed");
        return Err(WedprError::FormatError);
    }
    let point_value = match CompressedRistretto::from_slice(&point).decompress()
    {
        Some(v) => v,
        None => {
            wedpr_println!(
                "bytes_to_point decompress CompressedRistretto failed"
            );
            return Err(WedprError::FormatError);
        },
    };
    Ok(point_value)
}

/// Gets a random u32 integer.
pub fn get_random_u32() -> u32 {
    let mut rng = rand::thread_rng();
    let blinding: u32 = rng.gen();
    blinding
}