Skip to content

Commit 7a10808

Browse files
committed
Merge branch 'main' into testing/mvp
2 parents d9b7ad7 + b522013 commit 7a10808

File tree

8 files changed

+192
-118
lines changed

8 files changed

+192
-118
lines changed

onchain/cairo/afk/src/bip340.cairo

Lines changed: 87 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -17,47 +17,26 @@ use core::result::ResultTrait;
1717
use core::starknet::SyscallResultTrait;
1818
use core::to_byte_array::{AppendFormattedToByteArray, FormatAsByteArray};
1919
use core::traits::Into;
20-
use stark_vrf::{Error, generate_public_key, Proof, ScalarValue, StarkVRF};
2120
use starknet::{secp256k1::{Secp256k1Point}, secp256_trait::{Secp256Trait, Secp256PointTrait}};
22-
use super::request::SocialRequest;
21+
use super::social::{request::{SocialRequest,ConvertToBytes },transfer::Transfer, deposit::Claim, namespace::LinkedStarknetAddress};
22+
2323

2424
const TWO_POW_32: u128 = 0x100000000;
2525
const TWO_POW_64: u128 = 0x10000000000000000;
2626
const TWO_POW_96: u128 = 0x1000000000000000000000000;
2727

2828
const p: u256 = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F;
29-
pub impl EcPointDisplay of Display<EcPoint> {
30-
fn fmt(self: @EcPoint, ref f: Formatter) -> Result<(), Error> {
31-
let non_zero: NonZeroEcPoint = (*self).try_into().unwrap();
32-
let (x, y): (felt252, felt252) = ec_point_unwrap(non_zero);
33-
writeln!(f, "Point ({x}, {y})")
34-
}
35-
}
3629

3730
/// Represents a Schnorr signature
31+
#[derive(Drop)]
3832
struct SchnorrSignature {
3933
s: u256,
40-
R: u256,
34+
r: u256,
4135
}
4236

43-
// impl PartialEqImpl of PartialEq<EcPoint> {
44-
// fn eq(lhs: @EcPoint, rhs: @EcPoint) -> bool {
45-
// let (lhs_x, lhs_y): (felt252, felt252) = ec_point_unwrap((*lhs).try_into().unwrap());
46-
// let (rhs_x, rhs_y): (felt252, felt252) = ec_point_unwrap((*rhs).try_into().unwrap());
47-
48-
// }
49-
50-
// pub impl EcPointDisplay of Display<Secp256k1Point> {
51-
// fn fmt(self: @EcPoint, ref f: Formatter) -> Result<(), Error> {
52-
// let non_zero: NonZeroEcPoint = (*self).try_into().unwrap();
53-
// let (x, y): (u256, u256) = ec_point_unwrap(non_zero);
54-
// writeln!(f, "Point ({x}, {y})")
55-
// }
56-
// }
57-
5837
impl PartialEqImpl of PartialEq<EcPoint> {
5938
fn eq(lhs: @EcPoint, rhs: @EcPoint) -> bool {
60-
let (lhs_x, lhs_y): (u256, u256) = ec_point_unwrap((*lhs).try_into().unwrap());
39+
let (lhs_x, lhs_y): (felt252, felt252) = ec_point_unwrap((*lhs).try_into().unwrap());
6140
let (rhs_x, rhs_y): (felt252, felt252) = ec_point_unwrap((*rhs).try_into().unwrap());
6241

6342
if ((rhs_x == lhs_x) && (rhs_y == lhs_y)) {
@@ -176,66 +155,9 @@ pub fn verify(px: u256, rx: u256, s: u256, m: ByteArray) -> bool {
176155
// fail if is_infinite(R) || not has_even_y(R) || x(R) ≠ rx.
177156
!(Rx == 0 && Ry == 0) && Ry % 2 == 0 && Rx == rx
178157
}
179-
/// Represents a Schnorr signature
180-
struct SchnorrSignature {
181-
s: felt252,
182-
R: EcPoint,
183-
}
184-
185-
/// Generates a key pair (private key, public key) for Schnorr signatures
186-
fn generate_keypair() -> (felt252, EcPoint) {
187-
let generator: EcPoint = EcPointTrait::new(GEN_X, GEN_Y).unwrap();
188-
let private_key: felt252 = 859825214214312162317391210310; // VRF needed
189-
let public_key: EcPoint = generator.mul(private_key);
190-
191-
(private_key, public_key)
192-
}
193-
194-
/// Generates a nonce and corresponding R point for signature
195-
fn generate_nonce_point() -> (felt252, EcPoint) {
196-
let generator: EcPoint = EcPointTrait::new(GEN_X, GEN_Y).unwrap();
197-
let nonce: felt252 = 46952909012476409278523962123414653; // VRF needed
198-
let R: EcPoint = generator.mul(nonce);
199-
200-
(nonce, R)
201-
}
202-
203-
/// Computes the challenge hash e using Poseidon
204-
fn compute_challenge(R: EcPoint, public_key: EcPoint, message: felt252) -> felt252 {
205-
let (R_x, R_y): (felt252, felt252) = ec_point_unwrap(R.try_into().unwrap());
206-
let (P_x, P_y): (felt252, felt252) = ec_point_unwrap(public_key.try_into().unwrap());
207-
208-
PoseidonTrait::new().update(R_x).update(R_y).update(P_x).update(P_y).update(message).finalize()
209-
}
210-
211-
/// Signs a message using Schnorr signature scheme
212-
fn sign(private_key: felt252, message: felt252) -> SchnorrSignature {
213-
let (nonce, R) = generate_nonce_point();
214-
let generator: EcPoint = EcPointTrait::new(GEN_X, GEN_Y).unwrap();
215-
let public_key = generator.mul(private_key);
216-
217-
let e = compute_challenge(R, public_key, message);
218-
let s = nonce + mul_mod_p(private_key, e, ORDER);
219-
220-
SchnorrSignature { s, R }
221-
}
222-
223-
/// Verifies a Schnorr signature
224-
fn verify_sig(public_key: EcPoint, message: felt252, signature: SchnorrSignature) -> bool {
225-
let generator: EcPoint = EcPointTrait::new(GEN_X, GEN_Y).unwrap();
226-
let e = compute_challenge(signature.R, public_key, message);
227-
228-
let s_G: EcPoint = generator.mul(signature.s);
229-
let P_e: EcPoint = public_key.mul(e);
230-
let rhs: EcPoint = P_e + signature.R;
231-
232-
let (s_Gx, s_Gy): (felt252, felt252) = ec_point_unwrap(s_G.try_into().unwrap());
233-
let (rhs_x, rhs_y): (felt252, felt252) = ec_point_unwrap(rhs.try_into().unwrap());
234-
235-
(rhs_x == s_Gx) && (s_Gy == rhs_y)
236-
}
237158

238159
fn count_digits(mut num: u256) -> (u32, felt252) {
160+
let BASE: u256 = 16_u256;
239161
let mut count: u32 = 0;
240162
while num > 0 {
241163
num = num / BASE;
@@ -244,8 +166,65 @@ fn count_digits(mut num: u256) -> (u32, felt252) {
244166
let res: felt252 = count.try_into().unwrap();
245167
(count, res)
246168
}
169+
fn linkedStarknetAddress_to_bytes(linkedStarknetAddress: LinkedStarknetAddress) -> ByteArray {
170+
let mut ba: ByteArray = "";
171+
ba.append_word(linkedStarknetAddress.starknet_address.into(), 1_u32);
172+
ba
173+
}
174+
fn claim_to_bytes(claim: Claim) -> ByteArray{
175+
let mut ba: ByteArray = "";
176+
ba.append_word(claim.deposit_id.into(), 1_u32);
177+
ba.append_word(claim.starknet_recipient.into(), 1_u32);
178+
ba.append_word(claim.gas_token_address.into(), 1_u32);
179+
let (gas_count, gas_count_felt252) = count_digits(claim.gas_amount);
180+
let gas_felt252: felt252 = claim.gas_amount.try_into().unwrap();
181+
ba.append_word(gas_count_felt252, 1_u32);
182+
ba.append_word(gas_felt252, gas_count);
183+
ba
184+
}
185+
fn transfer_to_bytes(transfer :Transfer) -> ByteArray {
186+
let mut ba: ByteArray = "";
187+
// Encode amount (u256 to felt252 conversion)
188+
let (amount_count, amount_count_felt252) = count_digits(transfer.amount);
189+
let amount_felt252: felt252 = transfer.amount.try_into().unwrap();
190+
ba.append_word(amount_count_felt252, 1_u32);
191+
ba.append_word(amount_felt252, amount_count);
192+
193+
// Encode token
194+
ba.append_word(transfer.token, 1_u32);
195+
196+
// Encode token_address
197+
ba.append_word(transfer.token_address.into(), 1_u32);
198+
199+
// Encode joyboy (NostrProfile encoding)
200+
let (joyboy_count, joyboy_count_felt252) = count_digits(transfer.joyboy.public_key);
201+
let joyboy_felt252: felt252 = transfer.joyboy.public_key.try_into().unwrap();
202+
ba.append_word(joyboy_count_felt252, 1_u32);
203+
ba.append_word(joyboy_felt252, joyboy_count);
204+
for relay in transfer.joyboy.relays {
205+
ba.append(@relay);
206+
};
207+
208+
// Encode recipient (NostrProfile encoding)
209+
let (recipient_count, recipient_count_felt252) = count_digits(transfer.recipient.public_key);
210+
let recipient_felt252: felt252 = transfer.recipient.public_key.try_into().unwrap();
211+
ba.append_word(recipient_count_felt252, 1_u32);
212+
ba.append_word(recipient_felt252, recipient_count);
213+
for relay in transfer.recipient.relays{
214+
ba.append(@relay);
215+
};
216+
217+
// Encode recipient_address
218+
ba.append_word(transfer.recipient_address.into(), 1_u32);
219+
220+
ba
221+
}
247222

248-
fn encodeSocialRequest<C>(request: SocialRequest<C>) -> ByteArray {
223+
fn encodeSocialRequest<
224+
C,
225+
impl CImpl: ConvertToBytes<C>,
226+
impl CDrop: Drop<C>
227+
>(request: SocialRequest<C>) -> ByteArray {
249228
let mut ba: ByteArray = "";
250229

251230
// Encode public_key
@@ -269,13 +248,9 @@ fn encodeSocialRequest<C>(request: SocialRequest<C>) -> ByteArray {
269248
ba.append_word(kind_felt252, kind_count);
270249

271250
// Encode tags directly
272-
ba.append(request.tags);
273-
274-
// Encode content (assuming it can be converted to ByteArray) check needed
275-
let content_bytes = ByteArray::from(request.content);
276-
ba.append(content_bytes);
277-
278-
let (rx, _) = request.sig.R.get_coordinates().unwrap_syscall();
251+
ba.append(@request.tags);
252+
ba.append(@request.content.convert_to_bytes());
253+
let rx = request.sig.r;
279254
ba.append_word(rx.high.into(), 16);
280255
ba.append_word(rx.low.into(), 16);
281256
ba.append_word(request.sig.s.high.into(), 16);
@@ -303,9 +278,9 @@ fn generate_nonce_point() -> (u256, Secp256k1Point) {
303278
}
304279

305280
/// Computes the challenge hash e using Poseidon
306-
fn compute_challenge(R: EcPoint, public_key: EcPoint, message: ByteArray) -> felt252 {
307-
let (rx, _) = R.get_coordinates().unwrap_syscall();
308-
let (px, _) = public_key.get_coordinates().unwrap_syscall();
281+
fn compute_challenge(R: u256, public_key: Secp256k1Point, message: ByteArray) -> u256 {
282+
let rx= R;
283+
let (px,_tpx)= public_key.get_coordinates().unwrap_syscall() ;
309284

310285
hash_challenge(rx, px, message)
311286
}
@@ -314,9 +289,10 @@ fn sign(private_key: u256, message: ByteArray) -> SchnorrSignature {
314289
let (nonce, R) = generate_nonce_point();
315290
let G = Secp256Trait::<Secp256k1Point>::get_generator_point();
316291
let public_key = G.mul(private_key).unwrap_syscall();
317-
let (s_G_x, s_G_y) = public_key.get_coordinates().unwrap_syscall();
318-
let s_G_x = r;
319-
let e = compute_challenge(R, public_key, message);
292+
let (s_G_x, _s_G_y) = public_key.get_coordinates().unwrap_syscall();
293+
let r = s_G_x;
294+
let (x,_y) = R.get_coordinates().unwrap_syscall();
295+
let e = compute_challenge(x, public_key, message);
320296
let n = Secp256Trait::<Secp256k1Point>::get_curve_size();
321297

322298
// s = nonce + private_key * e mod n
@@ -326,21 +302,24 @@ fn sign(private_key: u256, message: ByteArray) -> SchnorrSignature {
326302
}
327303

328304
/// Verifies a Schnorr signature
329-
fn verify_sig(public_key: Secp256k1Point, message: u256, signature: SchnorrSignature) -> bool {
305+
fn verify_sig(public_key: Secp256k1Point, message: ByteArray, signature: SchnorrSignature) -> bool {
330306
let G = Secp256Trait::<Secp256k1Point>::get_generator_point();
331-
let e = compute_challenge(signature.R, public_key, message);
307+
let e = compute_challenge(signature.r, public_key, message);
332308
let n = Secp256Trait::<Secp256k1Point>::get_curve_size();
333-
309+
let (_nonce, R) = generate_nonce_point();
334310
// Check that s is within valid range
335-
if signature.s >= n {
311+
if (signature.s).into() >= n {
336312
return false;
337313
}
338314
// Verify s⋅G = R + e⋅P
339315
let s_G = G.mul(signature.s).unwrap_syscall();
340316
let e_P = public_key.mul(e).unwrap_syscall();
341-
let R_plus_eP = signature.R.add(e_P).unwrap_syscall();
342-
317+
// let R_plus_eP = e_P.add(R);
318+
let R_plus_eP = e_P.add(R).unwrap_syscall();
319+
/// Need to figure out add R
320+
343321
// Compare the points
322+
344323
let (s_G_x, s_G_y) = s_G.get_coordinates().unwrap_syscall();
345324
let (rhs_x, rhs_y) = R_plus_eP.get_coordinates().unwrap_syscall();
346325

@@ -591,10 +570,10 @@ mod tests {
591570
let (private_key, public_key) = generate_keypair();
592571

593572
// Message to sign
594-
let message: felt252 = 'I love Cairo';
573+
let message: ByteArray = "I love Cairo";
595574

596575
// Sign message
597-
let signature = sign(private_key, message);
576+
let signature = sign(private_key, message.clone());
598577

599578
// Verify signature
600579
let is_valid = verify_sig(public_key, message, signature);
@@ -607,10 +586,10 @@ mod tests {
607586
let (private_key, public_key) = generate_keypair();
608587

609588
// Message to sign
610-
let message: felt252 = 'I love Cairo';
589+
let message: ByteArray = "I love Cairo";
611590

612591
// Sign message
613-
let signature = sign(private_key, message);
592+
let signature = sign(private_key, message.clone());
614593

615594
// Verify signature
616595
let is_valid = verify_sig(public_key, message, signature);

onchain/cairo/afk/src/social/deposit.cairo

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use core::to_byte_array::FormatAsByteArray;
33
use core::traits::Into;
44
use starknet::{get_caller_address, get_contract_address, get_tx_info, ContractAddress};
55
use super::request::{SocialRequest, SocialRequestImpl, SocialRequestTrait, Encode, Signature};
6-
6+
use super::request::ConvertToBytes;
77
pub type DepositId = felt252;
88

99
#[derive(Clone, Debug, Drop, Serde)]
@@ -27,7 +27,32 @@ impl ClaimEncodeImpl of Encode<Claim> {
2727
)
2828
}
2929
}
30-
30+
fn count_digits(mut num: u256) -> (u32, felt252) {
31+
let BASE: u256 = 16_u256;
32+
let mut count: u32 = 0;
33+
while num > 0 {
34+
num = num / BASE;
35+
count = count + 1;
36+
};
37+
let res: felt252 = count.try_into().unwrap();
38+
(count, res)
39+
}
40+
impl ClaimImpl of ConvertToBytes<Claim> {
41+
fn convert_to_bytes(self: @Claim) -> ByteArray {
42+
let mut ba: ByteArray = "";
43+
let deposit_id: felt252 = *self.deposit_id;
44+
ba.append_word(deposit_id, 1_u32);
45+
let starknet_recipient: felt252 = (*self.starknet_recipient).into();
46+
ba.append_word(starknet_recipient, 1_u32);
47+
ba.append_word((*self.gas_token_address).into(), 1_u32);
48+
let gas_u256 = *self.gas_amount;
49+
let (gas_count, gas_count_felt252) = count_digits(gas_u256);
50+
let gas_felt252: felt252 = gas_u256.try_into().unwrap();
51+
ba.append_word(gas_count_felt252, 1_u32);
52+
ba.append_word(gas_felt252, gas_count);
53+
ba
54+
}
55+
}
3156
type NostrPublicKey = u256;
3257

3358
#[derive(Copy, Debug, Drop, Serde)]

onchain/cairo/afk/src/social/namespace.cairo

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use core::fmt::Display;
22
use core::to_byte_array::FormatAsByteArray;
33
use starknet::{get_caller_address, get_contract_address, get_tx_info, ContractAddress};
44
use super::request::{SocialRequest, SocialRequestImpl, SocialRequestTrait, Encode, Signature};
5+
use super::request::ConvertToBytes;
56

67
// Add this ROLE on a constants file
78
pub const OPERATOR_ROLE: felt252 = selector!("OPERATOR_ROLE");
@@ -34,7 +35,14 @@ impl LinkedStarknetAddressEncodeImpl of Encode<LinkedStarknetAddress> {
3435
@format!("link to {:?}", recipient_address_user_felt)
3536
}
3637
}
37-
38+
impl LinkedStarknetAddressImpl of ConvertToBytes<LinkedStarknetAddress> {
39+
fn convert_to_bytes(self: @LinkedStarknetAddress) -> ByteArray {
40+
let mut ba: ByteArray = "";
41+
let starknet_address_felt: felt252 = (*self.starknet_address).into();
42+
ba.append_word(starknet_address_felt, 1_u32);
43+
ba
44+
}
45+
}
3846
#[derive(Copy, Debug, Drop, Serde)]
3947
pub enum LinkedResult {
4048
Transfer: ContractAddress,

onchain/cairo/afk/src/social/request.cairo

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,9 @@ pub struct SocialRequest<C> {
2727
pub trait Encode<T> {
2828
fn encode(self: @T) -> @ByteArray;
2929
}
30-
30+
pub trait ConvertToBytes<T> {
31+
fn convert_to_bytes(self: @T) -> ByteArray;
32+
}
3133
#[generate_trait]
3234
pub impl SocialRequestImpl<C, +Encode<C>> of SocialRequestTrait<C> {
3335
fn verify(self: @SocialRequest<C>) -> Option<u256> {

0 commit comments

Comments
 (0)