From a2e14b0fc91cc5d4570fcb475505dada4d2e6ddd Mon Sep 17 00:00:00 2001 From: Logan Lamb Date: Fri, 9 Jun 2023 19:35:45 +0000 Subject: [PATCH] ed25519 signature malleability test like ed25519-dalek verify_strict by checking if the signature piece R and public key are small order --- src/ballet/ed25519/Local.mk | 2 + src/ballet/ed25519/fd_ed25519_ge.c | 60 +++++++++++++++++- src/ballet/ed25519/fd_ed25519_private.h | 4 +- src/ballet/ed25519/fd_ed25519_user.c | 2 + .../test_ed25519_signature_malleability.c | 53 ++++++++++++++++ ...519_signature_malleability_should_fail.bin | Bin 0 -> 18816 bytes ...519_signature_malleability_should_pass.bin | 1 + 7 files changed, 119 insertions(+), 3 deletions(-) create mode 100644 src/ballet/ed25519/test_ed25519_signature_malleability.c create mode 100644 src/ballet/ed25519/test_ed25519_signature_malleability_should_fail.bin create mode 100644 src/ballet/ed25519/test_ed25519_signature_malleability_should_pass.bin diff --git a/src/ballet/ed25519/Local.mk b/src/ballet/ed25519/Local.mk index 2f5cbc7c60..4b9632777f 100644 --- a/src/ballet/ed25519/Local.mk +++ b/src/ballet/ed25519/Local.mk @@ -1,4 +1,6 @@ $(call add-hdrs,fd_ed25519.h) $(call add-objs,fd_ed25519_fe fd_ed25519_ge fd_ed25519_user,fd_ballet) $(call make-unit-test,test_ed25519,test_ed25519,fd_ballet fd_util) +$(call make-unit-test,test_ed25519_signature_malleability,test_ed25519_signature_malleability,fd_ballet fd_util) $(call run-unit-test,test_ed25519,) +$(call run-unit-test,test_ed25519_signature_malleability,) diff --git a/src/ballet/ed25519/fd_ed25519_ge.c b/src/ballet/ed25519/fd_ed25519_ge.c index 6f296dd726..03c9087ea1 100644 --- a/src/ballet/ed25519/fd_ed25519_ge.c +++ b/src/ballet/ed25519/fd_ed25519_ge.c @@ -1,10 +1,66 @@ #include "fd_ed25519_private.h" -#if FD_ED25519_FE_IMPL==0 +#if FD_ED25519_FE_IMPL == 0 #include "ref/fd_ed25519_ge.c" -#elif FD_ED25519_FE_IMPL==1 +#elif FD_ED25519_FE_IMPL == 1 #include "avx/fd_ed25519_ge.c" #else #error "Unsupported FD_ED25519_FE_IMPL" #endif +static inline int +fd_ed25519_fe_eq( fd_ed25519_fe_t * const fe0, + fd_ed25519_fe_t * const fe1 ) { + return ( fe0->limb[ 0 ] == fe1->limb[ 0 ] ) & ( fe0->limb[ 1 ] == fe1->limb[ 1 ] ) & + ( fe0->limb[ 2 ] == fe1->limb[ 2 ] ) & ( fe0->limb[ 3 ] == fe1->limb[ 3 ] ) & + ( fe0->limb[ 4 ] == fe1->limb[ 4 ] ) & ( fe0->limb[ 5 ] == fe1->limb[ 5 ] ) & + ( fe0->limb[ 6 ] == fe1->limb[ 6 ] ) & ( fe0->limb[ 7 ] == fe1->limb[ 7 ] ) & + ( fe0->limb[ 8 ] == fe1->limb[ 8 ] ) & ( fe0->limb[ 9 ] == fe1->limb[ 9 ] ); +} + +static inline void +fd_ed25519_ge_p3_mul_by_pow_2( fd_ed25519_ge_p3_t * ret, + fd_ed25519_ge_p3_t * const p, + uint k ) { + /* If k is zero then return the original point p. [2^0]P = [1]P = P */ + if ( FD_UNLIKELY( k == 0 ) ) { + *ret = *p; + return; + } + fd_ed25519_ge_p1p1_t r[ 1 ]; + fd_ed25519_ge_p2_t s[ 1 ]; + fd_ed25519_ge_p3_to_p2( s, p ); + for( uint i = 0; i < ( k - 1 ); i++ ) { + fd_ed25519_ge_p2_dbl( r, s ); + fd_ed25519_ge_p1p1_to_p2( s, r ); + } + fd_ed25519_ge_p2_dbl( r, s ); + fd_ed25519_ge_p1p1_to_p3( ret, r ); +} + +static inline int +fd_ed25519_ge_p3_is_identity( fd_ed25519_ge_p3_t * const p ) { + fd_ed25519_ge_p3_t I[1]; + fd_ed25519_fe_0( I->X ); + fd_ed25519_fe_1( I->Y ); + fd_ed25519_fe_1( I->Z ); + fd_ed25519_fe_0( I->T ); + + fd_ed25519_fe_t cmp[2]; + fd_ed25519_fe_mul( &cmp[ 0 ], p->X, I->Z ); + fd_ed25519_fe_mul( &cmp[ 1 ], I->X, p->Z ); + int x = fd_ed25519_fe_eq( &cmp[ 0 ], &cmp[ 1 ] ); + + fd_ed25519_fe_mul( &cmp[ 0 ], p->Y, I->Z ); + fd_ed25519_fe_mul( &cmp[ 1 ], I->Y, p->Z ); + int y = fd_ed25519_fe_eq( &cmp[ 0 ], &cmp[ 1 ] ); + + return x & y; +} + +int +fd_ed25519_ge_p3_is_small_order( fd_ed25519_ge_p3_t * const p ) { + fd_ed25519_ge_p3_t t[ 1 ]; + fd_ed25519_ge_p3_mul_by_pow_2( t, p, 3 ); + return fd_ed25519_ge_p3_is_identity( t ); +} diff --git a/src/ballet/ed25519/fd_ed25519_private.h b/src/ballet/ed25519/fd_ed25519_private.h index 5cd0d018bc..88930bd288 100644 --- a/src/ballet/ed25519/fd_ed25519_private.h +++ b/src/ballet/ed25519/fd_ed25519_private.h @@ -37,7 +37,7 @@ struct fd_ed25519_ge_p2_private { fd_ed25519_fe_t Z[1]; }; -typedef struct fd_ed25519_ge_p2_private fd_ed25519_ge_p2_t; +typedef struct fd_ed25519_ge_p2_private fd_ed25519_ge_p2_t; struct fd_ed25519_ge_p3_private { fd_ed25519_fe_t X[1]; @@ -68,6 +68,8 @@ int fd_ed25519_ge_frombytes_vartime_2( fd_ed25519_ge_p3_t * h0, uchar const * s0, /* 32 */ fd_ed25519_ge_p3_t * h1, uchar const * s1 ); /* 32 */ +int fd_ed25519_ge_p3_is_small_order(fd_ed25519_ge_p3_t * const p); + static inline fd_ed25519_ge_p2_t * fd_ed25519_ge_p2_0( fd_ed25519_ge_p2_t * h ) { fd_ed25519_fe_0( h->X ); diff --git a/src/ballet/ed25519/fd_ed25519_user.c b/src/ballet/ed25519/fd_ed25519_user.c index 38274a8a98..2dc6986073 100644 --- a/src/ballet/ed25519/fd_ed25519_user.c +++ b/src/ballet/ed25519/fd_ed25519_user.c @@ -399,6 +399,8 @@ fd_ed25519_verify( void const * msg, (and hence an inversion) at the end */ fd_ed25519_ge_p3_t rD[1]; int err = fd_ed25519_ge_frombytes_vartime_2( A, public_key, rD, r ); if( FD_UNLIKELY( err ) ) return err; + if( fd_ed25519_ge_p3_is_small_order(A) ) return FD_ED25519_ERR_PUBKEY; + if( fd_ed25519_ge_p3_is_small_order(rD) ) return FD_ED25519_ERR_SIG; # else int err = fd_ed25519_ge_frombytes_vartime( A, public_key ); if( FD_UNLIKELY( err ) ) return err; # endif diff --git a/src/ballet/ed25519/test_ed25519_signature_malleability.c b/src/ballet/ed25519/test_ed25519_signature_malleability.c new file mode 100644 index 0000000000..636cbd246f --- /dev/null +++ b/src/ballet/ed25519/test_ed25519_signature_malleability.c @@ -0,0 +1,53 @@ +#include "../fd_ballet.h" + +struct verification_test { + uchar sig[ 64 ]; + uchar pub[ 32 ]; +}; +typedef struct verification_test verification_test_t; + +FD_IMPORT_BINARY(should_fail_bin, "src/ballet/ed25519/test_ed25519_signature_malleability_should_fail.bin"); +FD_IMPORT_BINARY(should_pass_bin, "src/ballet/ed25519/test_ed25519_signature_malleability_should_pass.bin"); +verification_test_t * const should_fail = ( verification_test_t * const ) should_fail_bin; +verification_test_t * const should_pass = ( verification_test_t * const ) should_pass_bin; + +int +main( int argc, + char ** argv ) { + fd_boot( &argc, &argv ); + fd_sha512_t _sha[1]; + fd_sha512_t *sha = fd_sha512_join(fd_sha512_new(_sha)); + uchar msg[] = "Zcash"; + + ulong should_fail_cnt = should_fail_bin_sz/sizeof(verification_test_t); + for( ulong i=0UL; i8?6ov73l$%7fSxpLJvpAs9sD}9vf*_a_ZkbaqXc7d$4>3WFMunMT6TxOR z_zy8%l-F-?f8pVsx@WJm?%B^?p5eMTwVyq-pIo^A@aFB$ci-MP^XTmPd*`lPJlI~{ z|8RWgY6Y3*;aj=KdL_FJ6HYhJMoz_KhV$qe=O`D`q@AD(Re5D zy;fZZ#QstBkw45&`Nw{df9b!F;*D@{fGW{6IhZN4{nM z(9izCkMLK0X#NsFeZ)H2r-A%oe&T?E{USfohkxd$^ii*6@x%OtfdT#p`c>9^xxYAI zAm1`S(9iynZ`nWevw!e|@l6xV4 zKl6k6a)0F?`NsT-`q@A7E&GRl_78p(KNI*k1pjLtAbs?cf9Z=aoX`8w`BfkOnV;2P z^$&iSpYjj>Ge0<=`-}d=nx9cW`$xVpKjk0#*+2LZ{(3)bz(4ad?mzjLKI(jbp?{B7%unfq|55#8zT98=ulX7Evw!3p^HctzpZ$X$;ln!kXMXa4-M=t) zmtDntn4dZU`$c}F5C43BN`L7(_+fs^ANU{YR~_@^{z|{*XVlOBk#CuQ=x6`nN7t+G z-?!kO`H6n*&(H^uKJth8DShl0`H?>SGe4!T`&C`~s#ksRKdL_F%l*~oulX7Evw!4U z<{$dmKll+o`u~&q{*?I%f8twp`bYjSKjk0$MSi3Y|IAP66A=7@^tIoR=X`a3)yI6f zzw%e}GwNsm$hXWt^s|55pYYN5BQyACen$R=K7jO*Kg>_*qfUO%Kf^!sQ~J7J)uj)9 z^!Eq(1pk>IeZG1>H9zGK`ph5cBi}Or(9izCkH$OUe)IS5(uYCvFMZ?>^HciZi~L9* z{+XZB$NjS`{hFWB2mhHL%$NHs|Eg;M>PJ2MN4{nLp`ZPOA6>ulGrvFM{3`!?zt#Ml zv0s%R`LFp&{sfTbyKsKa;6L+&`SSjBKd5JZpr8FC-?D$`XaC?w_)qYc-=ETlLGmws zyx*9g(#L+0AL+wC^Hch`f0m_R^HciZKl6k6a)0F?`Ih;Ce)g}=CxFzCdiD=~WMBE2 z-=FdGSN`>WtNEGVpSqug^OO7uAo*W7KlA%j{uj>A8TnT8Q~I30?g#bkANtw7~! A4gdfE literal 0 HcmV?d00001 diff --git a/src/ballet/ed25519/test_ed25519_signature_malleability_should_pass.bin b/src/ballet/ed25519/test_ed25519_signature_malleability_should_pass.bin new file mode 100644 index 0000000000..94a187682a --- /dev/null +++ b/src/ballet/ed25519/test_ed25519_signature_malleability_should_pass.bin @@ -0,0 +1 @@ +("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_("Bҙ;H,946S ɧ#VUs [qFo!>` @]Y OZԫ2?_ \ No newline at end of file