@@ -261,4 +261,225 @@ pub fn schnorr_verify(
261261 }
262262
263263 Ok ( ( ) )
264+ }
265+
266+ #[ cfg( test) ]
267+ mod tests {
268+ use super :: * ;
269+
270+ #[ test]
271+ fn test_schnorr_roundtrip ( ) {
272+ // Generate a key pair
273+ let ( secret_key, public_key) = generate_keypair ( ) ;
274+
275+ // Create test data
276+ let recipient_pubkey = public_key; // Use the generated public key as recipient
277+ let amount = 1000000000u64 ; // 1 ERG in nanoERG
278+ let timestamp = 1672531200u64 ; // Example timestamp
279+
280+ // Create the message to be signed
281+ let message = signing_message ( & recipient_pubkey, amount, timestamp) ;
282+
283+ // Sign the message
284+ let signature = schnorr_sign ( & message, & secret_key, & recipient_pubkey)
285+ . expect ( "Signing should succeed" ) ;
286+
287+ // Verify the signature
288+ schnorr_verify ( & signature, & message, & recipient_pubkey)
289+ . expect ( "Verification should succeed" ) ;
290+
291+ assert_eq ! ( signature. len( ) , 65 , "Signature should be 65 bytes" ) ;
292+ }
293+
294+ #[ test]
295+ fn test_schnorr_with_tampered_message ( ) {
296+ // Generate a key pair
297+ let ( secret_key, public_key) = generate_keypair ( ) ;
298+
299+ // Create test data
300+ let recipient_pubkey = public_key; // Use the generated public key as recipient
301+ let amount = 1000000000u64 ; // 1 ERG in nanoERG
302+ let timestamp = 1672531200u64 ; // Example timestamp
303+
304+ // Create the message to be signed
305+ let message = signing_message ( & recipient_pubkey, amount, timestamp) ;
306+
307+ // Sign the message
308+ let signature = schnorr_sign ( & message, & secret_key, & recipient_pubkey)
309+ . expect ( "Signing should succeed" ) ;
310+
311+ // Tamper with the message
312+ let mut tampered_message = message. clone ( ) ;
313+ tampered_message[ 0 ] ^= 0x01 ; // Flip one bit
314+
315+ // Verify with tampered message (should fail)
316+ let result = schnorr_verify ( & signature, & tampered_message, & recipient_pubkey) ;
317+
318+ assert ! ( result. is_err( ) , "Verification should fail with tampered message" ) ;
319+ }
320+
321+ #[ test]
322+ fn test_schnorr_with_wrong_public_key ( ) {
323+ // Generate two key pairs
324+ let ( secret_key1, public_key1) = generate_keypair ( ) ;
325+ let ( secret_key2, public_key2) = generate_keypair ( ) ;
326+
327+ // Create test data
328+ let recipient_pubkey = public_key1; // Use first public key as recipient
329+ let amount = 1000000000u64 ; // 1 ERG in nanoERG
330+ let timestamp = 1672531200u64 ; // Example timestamp
331+
332+ // Create the message to be signed
333+ let message = signing_message ( & recipient_pubkey, amount, timestamp) ;
334+
335+ // Sign the message with first party's key
336+ let signature = schnorr_sign ( & message, & secret_key1, & recipient_pubkey)
337+ . expect ( "Signing should succeed" ) ;
338+
339+ // Verify with second party's public key (should fail)
340+ let result = schnorr_verify ( & signature, & message, & public_key2) ;
341+
342+ assert ! ( result. is_err( ) , "Verification should fail with wrong public key" ) ;
343+ }
344+
345+ #[ test]
346+ fn test_signing_message_format ( ) {
347+ let recipient_pubkey = [ 0x02u8 ; 33 ] ; // Example public key
348+ let amount = 1000000000u64 ;
349+ let timestamp = 1672531200u64 ;
350+
351+ let message = signing_message ( & recipient_pubkey, amount, timestamp) ;
352+
353+ // Verify the format: recipient_pubkey (33 bytes) + amount_be_bytes (8 bytes) + timestamp_be_bytes (8 bytes)
354+ assert_eq ! ( message. len( ) , 33 + 8 + 8 , "Message should be 49 bytes" ) ;
355+ assert_eq ! ( & message[ 0 ..33 ] , & recipient_pubkey, "First 33 bytes should be recipient pubkey" ) ;
356+ assert_eq ! ( & message[ 33 ..41 ] , & amount. to_be_bytes( ) , "Next 8 bytes should be amount in big endian" ) ;
357+ assert_eq ! ( & message[ 41 ..49 ] , & timestamp. to_be_bytes( ) , "Last 8 bytes should be timestamp in big endian" ) ;
358+ }
359+
360+ #[ test]
361+ fn test_invalid_signature_length ( ) {
362+ // This test is actually testing the validation inside the function
363+ // Since the function signature requires [u8; 65], we can't pass a [u8; 64]
364+ // So instead we'll test the internal validation by creating a signature that fails validation
365+ let ( _, public_key) = generate_keypair ( ) ;
366+ let message = signing_message ( & public_key, 1000 , 1234567890 ) ;
367+
368+ // Create a signature with invalid 'a' component to trigger validation failure
369+ let mut invalid_signature = [ 0u8 ; 65 ] ;
370+ invalid_signature[ 0 ] = 0x01 ; // Invalid prefix (should be 0x02 or 0x03)
371+
372+ let result = schnorr_verify ( & invalid_signature, & message, & public_key) ;
373+ assert ! ( result. is_err( ) , "Verification should fail with invalid signature format" ) ;
374+ }
375+
376+ #[ test]
377+ fn test_invalid_signature_a_component ( ) {
378+ let ( _, public_key) = generate_keypair ( ) ;
379+ let message = signing_message ( & public_key, 1000 , 1234567890 ) ;
380+
381+ // Create a signature with invalid 'a' component (not a valid compressed point)
382+ let mut invalid_signature = [ 0u8 ; 65 ] ;
383+ invalid_signature[ 0 ] = 0x01 ; // Invalid prefix (should be 0x02 or 0x03)
384+
385+ let result = schnorr_verify ( & invalid_signature, & message, & public_key) ;
386+ assert ! ( result. is_err( ) , "Verification should fail with invalid 'a' component" ) ;
387+ }
388+
389+ #[ test]
390+ fn test_invalid_signature_z_component_all_zeros ( ) {
391+ let ( _, public_key) = generate_keypair ( ) ;
392+ let message = signing_message ( & public_key, 1000 , 1234567890 ) ;
393+
394+ // Create a signature with 'z' component all zeros
395+ let mut invalid_signature = [ 0u8 ; 65 ] ;
396+ invalid_signature[ 0 ] = 0x02 ; // Valid prefix
397+ // Leave the z component as all zeros (bytes 33-65)
398+
399+ let result = schnorr_verify ( & invalid_signature, & message, & public_key) ;
400+ assert ! ( result. is_err( ) , "Verification should fail with all-zeros 'z' component" ) ;
401+ }
402+
403+ #[ test]
404+ fn test_invalid_public_key_length ( ) {
405+ let ( secret_key, public_key) = generate_keypair ( ) ;
406+ let message = signing_message ( & public_key, 1000 , 1234567890 ) ;
407+
408+ // Sign with valid key
409+ let signature = schnorr_sign ( & message, & secret_key, & public_key)
410+ . expect ( "Signing should succeed" ) ;
411+
412+ // Create an invalid public key with wrong length
413+ let invalid_pubkey = [ 0x02u8 ; 32 ] ; // 32 bytes instead of 33
414+
415+ // Need to create a proper 33-byte array to pass to the function
416+ let mut invalid_pubkey_33 = [ 0x02u8 ; 33 ] ;
417+ invalid_pubkey_33[ 0 ] = 0x01 ; // Invalid prefix
418+
419+ let result = schnorr_verify ( & signature, & message, & invalid_pubkey_33) ;
420+ assert ! ( result. is_err( ) , "Verification should fail with invalid public key" ) ;
421+ }
422+
423+ #[ test]
424+ fn test_invalid_public_key_prefix ( ) {
425+ let ( secret_key, public_key) = generate_keypair ( ) ;
426+ let message = signing_message ( & public_key, 1000 , 1234567890 ) ;
427+
428+ // Sign with valid key
429+ let signature = schnorr_sign ( & message, & secret_key, & public_key)
430+ . expect ( "Signing should succeed" ) ;
431+
432+ // Create a public key with invalid prefix
433+ let mut invalid_pubkey = public_key;
434+ invalid_pubkey[ 0 ] = 0x01 ; // Invalid prefix (should be 0x02 or 0x03)
435+
436+ let result = schnorr_verify ( & signature, & message, & invalid_pubkey) ;
437+ assert ! ( result. is_err( ) , "Verification should fail with invalid public key prefix" ) ;
438+ }
439+
440+ #[ test]
441+ fn test_empty_message ( ) {
442+ let ( secret_key, public_key) = generate_keypair ( ) ;
443+ let empty_message: Vec < u8 > = vec ! [ ] ;
444+
445+ let result = schnorr_sign ( & empty_message, & secret_key, & public_key) ;
446+ // Signing with empty message should still work (the algorithm doesn't validate message content)
447+ if result. is_ok ( ) {
448+ let signature = result. unwrap ( ) ;
449+ let verify_result = schnorr_verify ( & signature, & empty_message, & public_key) ;
450+ assert ! ( verify_result. is_ok( ) , "Verification should succeed with empty message if signing worked" ) ;
451+ }
452+ }
453+
454+ #[ test]
455+ fn test_signature_with_modified_a_component ( ) {
456+ let ( secret_key, public_key) = generate_keypair ( ) ;
457+ let message = signing_message ( & public_key, 1000 , 1234567890 ) ;
458+
459+ // Sign the message
460+ let mut signature = schnorr_sign ( & message, & secret_key, & public_key)
461+ . expect ( "Signing should succeed" ) ;
462+
463+ // Modify the 'a' component (first 33 bytes)
464+ signature[ 0 ] ^= 0x01 ; // Flip a bit in the 'a' component
465+
466+ let result = schnorr_verify ( & signature, & message, & public_key) ;
467+ assert ! ( result. is_err( ) , "Verification should fail when 'a' component is modified" ) ;
468+ }
469+
470+ #[ test]
471+ fn test_signature_with_modified_z_component ( ) {
472+ let ( secret_key, public_key) = generate_keypair ( ) ;
473+ let message = signing_message ( & public_key, 1000 , 1234567890 ) ;
474+
475+ // Sign the message
476+ let mut signature = schnorr_sign ( & message, & secret_key, & public_key)
477+ . expect ( "Signing should succeed" ) ;
478+
479+ // Modify the 'z' component (bytes 33-65)
480+ signature[ 33 ] ^= 0x01 ; // Flip a bit in the 'z' component
481+
482+ let result = schnorr_verify ( & signature, & message, & public_key) ;
483+ assert ! ( result. is_err( ) , "Verification should fail when 'z' component is modified" ) ;
484+ }
264485}
0 commit comments