Skip to content

Commit

Permalink
🚧 prepare beginning of implementation of step1
Browse files Browse the repository at this point in the history
  • Loading branch information
AbdelStark committed Aug 2, 2024
1 parent daaeec3 commit e69f5ed
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 128 deletions.
110 changes: 19 additions & 91 deletions src/core.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -12,105 +12,33 @@ const TWO_POW_32: u128 = 0x100000000;
const TWO_POW_64: u128 = 0x10000000000000000;
const TWO_POW_96: u128 = 0x1000000000000000000000000;

/// Represents the Mint (Bob) in the BDHKE protocol
#[derive(Destruct)]
pub struct Mint {
pub k: u256, // Private key of the mint
pub K: Secp256k1Point, // Public key of the mint
}

/// Represents a User (Alice or Carol) in the BDHKE protocol
#[derive(Destruct)]
pub struct User {
/// Secret message
pub x: u256,
/// Point on the curve corresponding to x
pub Y: Secp256k1Point,
/// Blinding factor (private key for blinding)
pub r: u256,
}

/// Implements the Mint functionality
#[generate_trait()]
pub impl MintTraitImpl of MintTrait {
/// Creates a new Mint with a random private key
fn new(k: u256) -> Mint {
let K = Secp256Trait::<Secp256k1Point>::get_generator_point().mul(k).unwrap_syscall();
Mint { k, K }
}

/// Signs a blinded message
///
/// # Arguments
/// * `B_` - The blinded message point
///
/// # Returns
/// The blinded signature point C_
fn sign(ref self: Mint, B_: Secp256k1Point) -> Secp256k1Point {
B_.mul(self.k).unwrap_syscall()
}
// 2^16
const MAX_ATTEMPTS_HASH_TO_CURVE: u128 = 65536;

/// Verifies a token
///
/// # Arguments
/// * `x` - The secret message
/// * `C` - The unblinded signature point
///
/// # Returns
/// True if the token is valid, false otherwise
fn verify(self: Mint, x: u256, C: Secp256k1Point) -> bool {
let Y = hash_to_curve(x);
let expected_C_coordinates = Y
.mul(self.k)
.unwrap_syscall()
.get_coordinates()
.unwrap_syscall();
let c_coordinates = C.get_coordinates().unwrap_syscall();
expected_C_coordinates == c_coordinates
}
fn domain_separator() -> ByteArray {
"Secp256k1_HashToCurve_Cashu_"
}

/// Implements the User functionality
#[generate_trait()]
pub impl UserTraitImpl of UserTrait {
/// Creates a new User with a random secret message and blinding factor
fn new(x: u256, r: u256) -> User {
let Y = hash_to_curve(x);
User { x, Y, r }
}

/// Blinds the message
///
/// # Returns
/// The blinded message point B_
fn blind(ref self: User) -> Secp256k1Point {
let G = Secp256Trait::<Secp256k1Point>::get_generator_point();
self.Y.add(G.mul(self.r).unwrap_syscall()).unwrap_syscall()
}
pub fn step1_alice(secret_msg: ByteArray, blinding_factor: u256) -> (Secp256k1Point, u256) {
let msg_to_hash = domain_separator() + secret_msg;
println!("msg_to_hash: {msg_to_hash}");
let _hash = compute_sha256_byte_array(@msg_to_hash);

/// Unblinds the signature
///
/// # Arguments
/// * `C_` - The blinded signature point
/// * `K` - The mint's public key
///
/// # Returns
/// The unblinded signature point C
fn unblind(ref self: User, C_: Secp256k1Point, K: Secp256k1Point) -> Secp256k1Point {
C_.add(K.mul(self.r).unwrap_syscall()).unwrap_syscall()
}
let mut counter = 0;
while counter < MAX_ATTEMPTS_HASH_TO_CURVE {
counter += 1;
};

/// Creates a token
///
/// # Returns
/// A tuple containing the secret message and the unblinded signature point
fn create_token(ref self: User, C: Secp256k1Point) -> (u256, Secp256k1Point) {
(self.x, C)
}
// let B_ = Secp256Trait::<Secp256k1Point>::secp256_ec_get_point_from_x_syscall(0, false)
// .unwrap_syscall()
// .unwrap();
let B_ = Secp256Trait::<Secp256k1Point>::get_generator_point();
let r = blinding_factor;
(B_, r)
}


/// Hashes a message to a point on the secp256k1 curve
/// Generates a secp256k1 point from a message.
///
/// # Arguments
/// * `message` - The message to hash
Expand Down
40 changes: 5 additions & 35 deletions src/main.cairo
Original file line number Diff line number Diff line change
@@ -1,43 +1,13 @@
use bdhke::core::MintTrait;
use bdhke::core::MintTraitImpl;
use bdhke::core::UserTrait;
use bdhke::core::UserTraitImpl;
use starknet::{secp256k1::{Secp256k1Point}, secp256_trait::{Secp256Trait, Secp256PointTrait}};
use core::starknet::SyscallResultTrait;

use bdhke::core::step1_alice;

fn main() {
println!("Running Blind Diffie-Hellmann Key Exchange (BDHKE) scheme");

// Create a mint (Bob)
let mint_private_key: u256 = 0xe907831f80848d1069a5371b402410364bdf1c5f8307b0084c55f1ce2dca8215;
let mut mint = MintTraitImpl::new(mint_private_key);

// Create a user (Alice)
let alice_random_secret: u256 =
0xe907831f80848d1069a5371b402410364bdf1c5f8307b0084c55f1ce2dca8215;
let alice_blinding_factor: u256 =
0xe907831f80848d1069a5371b402410364bdf1c5f8307b0084c55f1ce2dca8215;

let mut alice = UserTraitImpl::new(alice_random_secret, alice_blinding_factor);

// Alice blinds her message
let B_ = alice.blind();

// Mint signs the blinded message
let C_ = mint.sign(B_);

// Alice unblinds the signature
let C = alice.unblind(C_, mint.K);

// Alice creates a token
let (x, C) = alice.create_token(C);

// Mint verifies the token
let is_valid = mint.verify(x, C);
let mut secret_msg = "test_message";
let blinding_factor: u256 = 0xe907831f80848d1069a5371b402410364bdf1c5f8307b0084c55f1ce2dca8215;

if is_valid {
println!("Token is valid");
} else {
println!("Token is invalid");
}
let (B_, r) = step1_alice(secret_msg, blinding_factor);
}
Binary file not shown.
5 changes: 3 additions & 2 deletions tests/references/bdhke-nutshell/bdhke_nutshell.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ def log(message):
)
A = a.pubkey
assert A, "Failed to generate Alice's public key"
log(f"Alice's private key (a): {a.private_key.hex()}")
log(f"Alice's public key (A): {A.serialize().hex()}")
assert (
A.serialize().hex()
Expand Down Expand Up @@ -59,8 +60,8 @@ def log(message):
log("Step 4: Bob signs the blinded message")
C_, e, s = step2_bob(B_, a)
log(f"Blinded signature (C_): {C_.serialize().hex()}")
log(f"DLEQ proof - e: {e}") # e is already a string
log(f"DLEQ proof - s: {s}") # s is already a string
log(f"DLEQ proof - e: {e.serialize()}")
log(f"DLEQ proof - s: {s.serialize()}")

# Step 5: Alice verifies the DLEQ proof
log("Step 5: Alice verifies the DLEQ proof")
Expand Down

0 comments on commit e69f5ed

Please sign in to comment.