-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
7b9dc9b
commit b857f0e
Showing
8 changed files
with
267 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
all | ||
# lame rules | ||
exclude_rule 'MD002' | ||
exclude_rule 'MD041' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
all | ||
# allow inline HTML for README fmt | ||
exclude_rule 'MD033' | ||
# badges trigger rule | ||
exclude_rule 'MD034' | ||
# README img serves as 'First Header' | ||
exclude_rule 'MD002' | ||
exclude_rule 'MD041' | ||
# TODO: disable/enable not working for all-contribs | ||
exclude_rule 'MD013' | ||
# Allow no endline at the end | ||
exclude_rule 'MD047' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
scarb 2.6.3 | ||
scarb 2.7.0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,3 +4,7 @@ version = "0.1.0" | |
edition = "2023_11" | ||
|
||
[dependencies] | ||
starknet = "2.7.0" | ||
|
||
[dev-dependencies] | ||
cairo_test = "2.7.0" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,170 @@ | ||
// Core lib imports | ||
use core::traits::Into; | ||
use core::option::OptionTrait; | ||
use core::starknet::SyscallResultTrait; | ||
use core::sha256::compute_sha256_byte_array; | ||
|
||
// Starknet imports | ||
use starknet::{secp256k1::{Secp256k1Point}, secp256_trait::{Secp256Trait, Secp256PointTrait}}; | ||
|
||
|
||
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() | ||
} | ||
|
||
/// 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 | ||
} | ||
} | ||
|
||
/// 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() | ||
} | ||
|
||
/// 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() | ||
} | ||
|
||
/// 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) | ||
} | ||
} | ||
|
||
|
||
/// Hashes a message to a point on the secp256k1 curve | ||
/// | ||
/// # Arguments | ||
/// * `message` - The message to hash | ||
/// | ||
/// # Returns | ||
/// A point on the secp256k1 curve | ||
pub fn hash_to_curve(message: u256) -> Secp256k1Point { | ||
// This is a simplified implementation. In practice, you should use a more | ||
// robust method to ensure the resulting point is uniformly distributed. | ||
let mut attempt = 0; | ||
loop { | ||
let hash_input = message * TWO_POW_32.into() + attempt.into(); | ||
let hash_result = compute_hash(hash_input); | ||
match Secp256Trait::< | ||
Secp256k1Point | ||
>::secp256_ec_get_point_from_x_syscall(hash_result, false) { | ||
Result::Ok(point_option) => { | ||
match point_option { | ||
Option::Some(point) => { break point; }, | ||
Option::None => { attempt += 1; } | ||
} | ||
}, | ||
Result::Err(_) => { attempt += 1; } | ||
} | ||
} | ||
} | ||
|
||
/// Computes a hash of the input | ||
/// | ||
/// # Arguments | ||
/// * `input` - The input to hash | ||
/// | ||
/// # Returns | ||
/// The hash result as a u256 | ||
pub fn compute_hash(input: u256) -> u256 { | ||
let hash_result = compute_sha256_byte_array(@input.into()); | ||
let mut value: u256 = 0; | ||
let hash_result_span = hash_result.span(); | ||
let len = hash_result_span.len(); | ||
let mut i = 0; | ||
while i < len { | ||
let word = hash_result_span[i]; | ||
value *= 0x100000000; | ||
value = value + (*word).into(); | ||
i += 1; | ||
}; | ||
value | ||
} | ||
|
||
pub impl U256IntoByteArray of Into<u256, ByteArray> { | ||
fn into(self: u256) -> ByteArray { | ||
let mut ba = Default::default(); | ||
ba.append_word(self.high.into(), 16); | ||
ba.append_word(self.low.into(), 16); | ||
ba | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,2 @@ | ||
mod main; | ||
pub mod core; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,43 @@ | ||
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; | ||
|
||
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); | ||
|
||
if is_valid { | ||
println!("Token is valid"); | ||
} else { | ||
println!("Token is invalid"); | ||
} | ||
} |