Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add ecdh psi interface #50

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
229 changes: 190 additions & 39 deletions Cargo.lock

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ members = [
"ffi/ffi_c/ffi_c_crypto_binary",
"ffi/ffi_c/ffi_c_fisco_bcos",
"ffi/ffi_c/ffi_c_zkp",
"ffi/ffi_c/ffi_c_ecc_edwards25519",
"ffi/ffi_common",
"ffi/ffi_java/ffi_java_crypto",
"ffi/ffi_java/ffi_java_crypto_binary",
Expand All @@ -34,4 +35,7 @@ members = [
"protos",
"third_party/fisco_bcos",
"third_party/fisco_bcos_java_sdk",
"crypto/ecc/ecc_edwards25519",
"ffi/ffi_java/ffi_java_ecc_edwards25519",
"ffi/ffi_wasm/ffi_wasm_ecc_edwards25519",
]
16 changes: 16 additions & 0 deletions crypto/ecc/ecc_edwards25519/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[package]
name = "ecc_edwards25519"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html


[dependencies]
sha2 = "0.10.7"
rand = "0.8.4"
rand_core = "0.6.3"
curve25519-dalek = { version = "4", features = [ "digest" , "rand_core"] }

[lib]
crate-type = ["cdylib", "rlib"]
86 changes: 86 additions & 0 deletions crypto/ecc/ecc_edwards25519/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
use curve25519_dalek::{
ristretto::CompressedRistretto, RistrettoPoint, Scalar,
};
use rand::rngs::ThreadRng;
use sha2::Sha512;

const SCALAR_SIZE: usize = 32;
const POINT_SIZE: usize = 32;

pub fn random_scalar() -> Vec<u8> {
// 创建一个随机数生成器
let mut rng: ThreadRng = rand::thread_rng();

// 生成一个随机的 Scalar
let scalar = Scalar::random(&mut rng);

// 将 Scalar 转换成 &[u8]
scalar.to_bytes().to_vec()
}

pub fn hash_to_curve(message: &[u8]) -> Vec<u8> {
let hash_point = RistrettoPoint::hash_from_bytes::<Sha512>(message);
return hash_point.compress().to_bytes().to_vec();
}

pub fn point_scalar_multi(point: &[u8], scalar: &[u8]) -> Vec<u8> {
// 检查输入切片是否具有正确的大小
if point.len() != POINT_SIZE || scalar.len() != SCALAR_SIZE {
return Vec::new(); // 如果大小不正确,返回空的 Vec<u8>
}

// 将输入 &[u8] 转换成 CompressedRistretto 表示的点
let compressed_point = match CompressedRistretto::from_slice(&point) {
Ok(point) => point,
Err(_) => return Vec::new(), // 解析点失败,返回空的 Vec<u8>
};
let point = match compressed_point.decompress() {
Some(point) => point,
None => return Vec::new(), // 解析点失败,返回空的 Vec<u8>
};

// 将输入 &[u8] 转换成 Scalar
let mut scalar_bytes = [0u8; SCALAR_SIZE];
scalar_bytes.copy_from_slice(scalar);
let scalar = Scalar::from_bytes_mod_order(scalar_bytes);

// 执行点乘操作
let result_point = point * scalar;

// 将结果转换成压缩格式的点
let compressed_result = result_point.compress();

// 将结果转换成 &[u8]
compressed_result.as_bytes().to_vec()
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_edwards25519() {
let message = "hello world".as_bytes();
// let key = random_scalar();
let key = [
125, 185, 175, 119, 127, 247, 65, 76, 146, 163, 142, 178, 247, 149,
185, 187, 132, 19, 67, 161, 231, 145, 164, 133, 64, 64, 220, 138,
248, 231, 43, 7,
];
let point = hash_to_curve(&message);
let result = point_scalar_multi(&point, &key);
let expected: Vec<u8> = [
74, 210, 113, 116, 176, 64, 232, 75, 240, 244, 198, 94, 19, 27,
194, 225, 169, 80, 205, 176, 169, 190, 206, 56, 52, 218, 142, 79,
28, 132, 70, 16,
]
.to_vec();
assert_eq!(expected, result);
}

#[test]
fn test_empty_vector() {
let test_vector: Vec<u8> = Vec::new();
assert_eq!(test_vector.is_empty(), true);
}
}
17 changes: 7 additions & 10 deletions crypto/signature/secp256k1/benches/secp256k1.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
// Copyright 2021 WeDPR Lab Project Authors. Licensed under Apache-2.0.

use criterion::Criterion;
use wedpr_l_crypto_signature_secp256k1::{WedprSecp256k1Recover};
use wedpr_l_utils::traits::Signature;
use wedpr_l_utils::constant::tests::BASE64_ENCODED_TEST_MESSAGE;
use wedpr_l_crypto_signature_secp256k1::WedprSecp256k1Recover;
use wedpr_l_utils::{
constant::tests::BASE64_ENCODED_TEST_MESSAGE, traits::Signature,
};

#[macro_use]
extern crate criterion;

fn create_sign_helper(c: &mut Criterion, message_size: usize) {
let label =
format!("create_sign_helper, message_size = {}", message_size);
let label = format!("create_sign_helper, message_size = {}", message_size);
let secp256k1 = WedprSecp256k1Recover::default();
let (pk_b, sk_b) = secp256k1.generate_keypair();

Expand All @@ -26,20 +26,17 @@ fn create_sign_helper(c: &mut Criterion, message_size: usize) {
fn create_verify_helper(c: &mut Criterion, message_size: usize) {
let label =
format!("create_verify_helper, message_size = {}", message_size);
let label =
format!("create_sign_helper, message_size = {}", message_size);
let label = format!("create_sign_helper, message_size = {}", message_size);
let secp256k1 = WedprSecp256k1Recover::default();
let (pk_b, sk_b) = secp256k1.generate_keypair();

let message = BASE64_ENCODED_TEST_MESSAGE;

let sign_obj = secp256k1.sign(&sk_b, &message.to_vec()).unwrap();


c.bench_function(&label, move |b| {
b.iter(|| {
let _ = secp256k1
.recover_public_key(&message.to_vec(), &sign_obj);
let _ = secp256k1.recover_public_key(&message.to_vec(), &sign_obj);
})
});
}
Expand Down
23 changes: 11 additions & 12 deletions crypto/signature/secp256k1/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ extern crate lazy_static;

extern crate secp256k1;
use secp256k1::{
ecdsa::{RecoverableSignature, RecoveryId},
rand::rngs::OsRng,
All, Message, PublicKey, Secp256k1, SecretKey, VerifyOnly,
};
use secp256k1::ecdsa::{RecoverableSignature, RecoveryId};
use wedpr_l_utils::{error::WedprError, traits::Signature};
use secp256k1::rand::rngs::OsRng;

lazy_static! {
// Shared secp256k1 instance initialized for verification function only.
Expand All @@ -22,7 +22,6 @@ lazy_static! {
static ref SECP256K1_ALL: Secp256k1<All> = Secp256k1::new();
}


/// Implements FISCO-BCOS-compatible Secp256k1 as a Signature instance.
#[derive(Default, Debug, Clone, Copy)]
pub struct WedprSecp256k1Recover {}
Expand Down Expand Up @@ -99,7 +98,6 @@ impl Signature for WedprSecp256k1Recover {

fn generate_keypair(&self) -> (Vec<u8>, Vec<u8>) {
loop {

let (secret_key, public_key) =
SECP256K1_ALL.generate_keypair(&mut OsRng);

Expand Down Expand Up @@ -155,14 +153,15 @@ impl WedprSecp256k1Recover {
return Err(WedprError::FormatError);
},
};
let recovered_public_key =
match SECP256K1_VERIFY.recover_ecdsa(&msg_hash_obj, &get_sign_final) {
Ok(v) => v,
Err(_) => {
wedpr_println!("Signature recover failed");
return Err(WedprError::FormatError);
},
};
let recovered_public_key = match SECP256K1_VERIFY
.recover_ecdsa(&msg_hash_obj, &get_sign_final)
{
Ok(v) => v,
Err(_) => {
wedpr_println!("Signature recover failed");
return Err(WedprError::FormatError);
},
};
return Ok(recovered_public_key.serialize_uncompressed().to_vec());
}

Expand Down
18 changes: 18 additions & 0 deletions ffi/ffi_c/ffi_c_ecc_edwards25519/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
[package]
name = "wedpr_ffi_c_edwards25519"
version = "1.0.0"
authors = [ "WeDPR <[email protected]>" ]
edition = "2018"

[lib]
name = "ffi_c_edwards25519"
crate-type = [ "cdylib", "staticlib" ]

[dependencies]
libc = "0.2.60"
ecc_edwards25519 = { path = "../../../crypto/ecc/ecc_edwards25519" }
wedpr_ffi_common = { path = "../../ffi_common" }

# This is required to generate C/C++ header files.
[build-dependencies]
cbindgen = "0.9.0"
49 changes: 49 additions & 0 deletions ffi/ffi_c/ffi_c_ecc_edwards25519/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
//! Library of FFI of wedpr_crypto wrapper functions, targeting C/C++
//! compatible architectures (including iOS), with fast binary interfaces.
// Copyright 2020 WeDPR Lab Project Authors. Licensed under Apache-2.0.

use ecc_edwards25519::{hash_to_curve, point_scalar_multi, random_scalar};

use wedpr_ffi_common::utils::{c_read_raw_pointer, c_write_raw_pointer, CInputBuffer, COutputBuffer, FAILURE, SUCCESS};

#[no_mangle]
/// C interface for 'wedpr_random_scalar'.
pub unsafe extern "C" fn wedpr_random_scalar(
output_ciphertext: &mut COutputBuffer,
) -> i8 {
let random_scalar = random_scalar();
c_write_raw_pointer(&random_scalar, output_ciphertext);
SUCCESS
}

#[no_mangle]
/// C interface for 'wedpr_hash_to_curve'.
pub unsafe extern "C" fn wedpr_hash_to_curve(
raw_message: &CInputBuffer,
output_ciphertext: &mut COutputBuffer,
) -> i8 {
let plaintext = c_read_raw_pointer(raw_message);
let message = hash_to_curve(&plaintext);
std::mem::forget(plaintext);
c_write_raw_pointer(&message, output_ciphertext);
SUCCESS
}

#[no_mangle]
/// C interface for 'wedpr_point_scalar_multi'.
pub unsafe extern "C" fn wedpr_point_scalar_multi(
raw_point: &CInputBuffer,
raw_scalar: &CInputBuffer,
output_ciphertext: &mut COutputBuffer,
) -> i8 {
let num_point = c_read_raw_pointer(raw_point);
let num_scalar = c_read_raw_pointer(raw_scalar);
let result = point_scalar_multi(&num_point, &num_scalar);
std::mem::forget(num_point);
std::mem::forget(num_scalar);
if result.is_empty() {
return FAILURE;
}
c_write_raw_pointer(&result, output_ciphertext);
SUCCESS
}
14 changes: 14 additions & 0 deletions ffi/ffi_java/ffi_java_ecc_edwards25519/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[package]
name = "ffi_java_ecc_edwards25519"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[lib]
name = "ffi_java_ecc_edwards25519"
crate-type = [ "cdylib", "staticlib" ]

[dependencies]
jni = "0.13.0"
ecc_edwards25519 = { path = "../../../crypto/ecc/ecc_edwards25519" }
71 changes: 71 additions & 0 deletions ffi/ffi_java/ffi_java_ecc_edwards25519/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
extern crate jni;

use ecc_edwards25519::{hash_to_curve, point_scalar_multi, random_scalar};

use jni::{objects::JClass, sys::jbyteArray, JNIEnv};

// 导出函数给JNI接口调用

#[no_mangle]
pub extern "system" fn Java_com_webank_wedpr_crypto_NativeInterface_randomScalar(
env: JNIEnv,
_class: JClass,
) -> jbyteArray {
// 调用原始函数
let result = random_scalar();

// 将 Vec<u8> 转换成 jbyteArray 并返回给Java层
match env.byte_array_from_slice(&result) {
Ok(array) => array,
Err(_) => env.new_byte_array(0).unwrap(), // 返回空的 jbyteArray
}
}

#[no_mangle]
pub extern "system" fn Java_com_webank_wedpr_crypto_NativeInterface_hashToCurve(
env: JNIEnv,
_class: JClass,
message: jbyteArray,
) -> jbyteArray {
// 将 jbyteArray 转换成 Vec<u8>
let message_bytes = match env.convert_byte_array(message) {
Ok(bytes) => bytes,
Err(_) => return env.new_byte_array(0).unwrap(), /* 返回空的 jbyteArray */
};

// 调用原始函数
let result = hash_to_curve(&message_bytes);

// 将 Vec<u8> 转换成 jbyteArray 并返回给Java层
match env.byte_array_from_slice(&result) {
Ok(array) => array,
Err(_) => env.new_byte_array(0).unwrap(), // 返回空的 jbyteArray
}
}

#[no_mangle]
pub extern "system" fn Java_com_webank_wedpr_crypto_NativeInterface_pointScalarMulti(
env: JNIEnv,
_class: JClass,
point: jbyteArray,
scalar: jbyteArray,
) -> jbyteArray {
// 将 jbyteArray 转换成 Vec<u8>
let point_bytes = match env.convert_byte_array(point) {
Ok(bytes) => bytes,
Err(_) => return env.new_byte_array(0).unwrap(), /* 返回空的 jbyteArray */
};
let scalar_bytes = match env.convert_byte_array(scalar) {
Ok(bytes) => bytes,
Err(_) => return env.new_byte_array(0).unwrap(), /* 返回空的 jbyteArray */
};

// 调用原始函数
let result = point_scalar_multi(&point_bytes, &scalar_bytes);

// 将 Vec<u8> 转换成 jbyteArray 并返回给Java层
match env.byte_array_from_slice(&result) {
Ok(array) => array,
Err(_) => env.new_byte_array(0).unwrap(), // 返回空的 jbyteArray
}
}
14 changes: 14 additions & 0 deletions ffi/ffi_wasm/ffi_wasm_ecc_edwards25519/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[package]
name = "ffi_wasm_ecc_edwards25519"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[lib]
name = "ffi_wasm_ecc_edwards25519"
crate-type = ["rlib", "cdylib"]

[dependencies]
wasm-bindgen = "0.2"
getrandom = { version = "0.2", features = ["js"] }
ecc_edwards25519 = { path = "../../../crypto/ecc/ecc_edwards25519" }
Loading
Loading