<s> """<STR_LIT>""" <EOL> import hashlib <EOL> import operator <EOL> import sys <EOL> __version__ = "<STR_LIT>" <EOL> PY3 = sys . version_info [ <NUM_LIT:0> ] == <NUM_LIT:3> <EOL> if PY3 : <EOL> indexbytes = operator . getitem <EOL> intlist2bytes = bytes <EOL> int2byte = operator . methodcaller ( "<STR_LIT>" , <NUM_LIT:1> , "<STR_LIT>" ) <EOL> else : <EOL> int2byte = chr <EOL> range = xrange <EOL> def indexbytes ( buf , i ) : <EOL> return ord ( buf [ i ] ) <EOL> def intlist2bytes ( l ) : <EOL> return b"<STR_LIT>" . join ( chr ( c ) for c in l ) <EOL> b = <NUM_LIT> <EOL> q = <NUM_LIT:2> ** <NUM_LIT:255> - <NUM_LIT> <EOL> l = <NUM_LIT:2> ** <NUM_LIT> + <NUM_LIT> <EOL> def H ( m ) : <EOL> return hashlib . sha512 ( m ) . digest ( ) <EOL> def pow2 ( x , p ) : <EOL> """<STR_LIT>""" <EOL> while p > <NUM_LIT:0> : <EOL> x = x * x % q <EOL> p -= <NUM_LIT:1> <EOL> return x <EOL> def inv ( z ) : <EOL> """<STR_LIT>""" <EOL> z2 = z * z % q <EOL> z9 = pow2 ( z2 , <NUM_LIT:2> ) * z % q <EOL> z11 = z9 * z2 % q <EOL> z2_5_0 = ( z11 * z11 ) % q * z9 % q <EOL> z2_10_0 = pow2 ( z2_5_0 , <NUM_LIT:5> ) * z2_5_0 % q <EOL> z2_20_0 = pow2 ( z2_10_0 , <NUM_LIT:10> ) * z2_10_0 % q <EOL> z2_40_0 = pow2 ( z2_20_0 , <NUM_LIT:20> ) * z2_20_0 % q <EOL> z2_50_0 = pow2 ( z2_40_0 , <NUM_LIT:10> ) * z2_10_0 % q <EOL> z2_100_0 = pow2 ( z2_50_0 , <NUM_LIT:50> ) * z2_50_0 % q <EOL> z2_200_0 = pow2 ( z2_100_0 , <NUM_LIT:100> ) * z2_100_0 % q <EOL> z2_250_0 = pow2 ( z2_200_0 , <NUM_LIT:50> ) * z2_50_0 % q <EOL> return pow2 ( z2_250_0 , <NUM_LIT:5> ) * z11 % q <EOL> d = - <NUM_LIT> * inv ( <NUM_LIT> ) % q <EOL> I = pow ( <NUM_LIT:2> , ( q - <NUM_LIT:1> ) // <NUM_LIT:4> , q ) <EOL> def xrecover ( y ) : <EOL> xx = ( y * y - <NUM_LIT:1> ) * inv ( d * y * y + <NUM_LIT:1> ) <EOL> x = pow ( xx , ( q + <NUM_LIT:3> ) // <NUM_LIT:8> , q ) <EOL> if ( x * x - xx ) % q != <NUM_LIT:0> : <EOL> x = ( x * I ) % q <EOL> if x % <NUM_LIT:2> != <NUM_LIT:0> : <EOL> x = q - x <EOL> return x <EOL> By = <NUM_LIT:4> * inv ( <NUM_LIT:5> ) <EOL> Bx = xrecover ( By ) <EOL> B = ( Bx % q , By % q , <NUM_LIT:1> , ( Bx * By ) % q ) <EOL> ident = ( <NUM_LIT:0> , <NUM_LIT:1> , <NUM_LIT:1> , <NUM_LIT:0> ) <EOL> def edwards_add ( P , Q ) : <EOL> ( x1 , y1 , z1 , t1 ) = P <EOL> ( x2 , y2 , z2 , t2 ) = Q <EOL> a = ( y1 - x1 ) * ( y2 - x2 ) % q <EOL> b = ( y1 + x1 ) * ( y2 + x2 ) % q <EOL> c = t1 * <NUM_LIT:2> * d * t2 % q <EOL> dd = z1 * <NUM_LIT:2> * z2 % q <EOL> e = b - a <EOL> f = dd - c <EOL> g = dd + c <EOL> h = b + a <EOL> x3 = e * f <EOL> y3 = g * h <EOL> t3 = e * h <EOL> z3 = f * g <EOL> return ( x3 % q , y3 % q , z3 % q , t3 % q ) <EOL> def edwards_double ( P ) : <EOL> ( x1 , y1 , z1 , t1 ) = P <EOL> a = x1 * x1 % q <EOL> b = y1 * y1 % q <EOL> c = <NUM_LIT:2> * z1 * z1 % q <EOL> e = ( ( x1 + y1 ) * ( x1 + y1 ) - a - b ) % q <EOL> g = - a + b <EOL> f = g - c <EOL> h = - a - b <EOL> x3 = e * f <EOL> y3 = g * h <EOL> t3 = e * h <EOL> z3 = f * g <EOL> return ( x3 % q , y3 % q , z3 % q , t3 % q ) <EOL> def scalarmult ( P , e ) : <EOL> if e == <NUM_LIT:0> : <EOL> return ident <EOL> Q = scalarmult ( P , e // <NUM_LIT:2> ) <EOL> Q = edwards_double ( Q ) <EOL> if e & <NUM_LIT:1> : <EOL> Q = edwards_add ( Q , P ) <EOL> return Q <EOL> Bpow = [ ] <EOL> def make_Bpow ( ) : <EOL> P = B <EOL> for i in range ( <NUM_LIT> ) : <EOL> Bpow . append ( P ) <EOL> P = edwards_double ( P ) <EOL> make_Bpow ( ) <EOL> def scalarmult_B ( e ) : <EOL> """<STR_LIT>""" <EOL> e = e % l <EOL> P = ident <EOL> for i in range ( <NUM_LIT> ) : <EOL> if e & <NUM_LIT:1> : <EOL> P = edwards_add ( P , Bpow [ i ] ) <EOL> e = e // <NUM_LIT:2> <EOL> assert e == <NUM_LIT:0> , e <EOL> return P <EOL> def encodeint ( y ) : <EOL> bits = [ ( y >> i ) & <NUM_LIT:1> for i in range ( b ) ] <EOL> return b'<STR_LIT>' . join ( [ <EOL> int2byte ( sum ( [ bits [ i * <NUM_LIT:8> + j ] << j for j in range ( <NUM_LIT:8> ) ] ) ) <EOL> for i in range ( b // <NUM_LIT:8> ) <EOL> ] ) <EOL> def encodepoint ( P ) : <EOL> ( x , y , z , t ) = P <EOL> zi = inv ( z ) <EOL> x = ( x * zi ) % q <EOL> y = ( y * zi ) % q <EOL> bits = [ ( y >> i ) & <NUM_LIT:1> for i in range ( b - <NUM_LIT:1> ) ] + [ x & <NUM_LIT:1> ] <EOL> return b'<STR_LIT>' . join ( [ <EOL> int2byte ( sum ( [ bits [ i * <NUM_LIT:8> + j ] << j for j in range ( <NUM_LIT:8> ) ] ) ) <EOL> for i in range ( b // <NUM_LIT:8> ) <EOL> ] ) <EOL> def bit ( h , i ) : <EOL> return ( indexbytes ( h , i // <NUM_LIT:8> ) >> ( i % <NUM_LIT:8> ) ) & <NUM_LIT:1> <EOL> def publickey_unsafe ( sk ) : <EOL> """<STR_LIT>""" <EOL> h = H ( sk ) <EOL> a = <NUM_LIT:2> ** ( b - <NUM_LIT:2> ) + sum ( <NUM_LIT:2> ** i * bit ( h , i ) for i in range ( <NUM_LIT:3> , b - <NUM_LIT:2> ) ) <EOL> A = scalarmult_B ( a ) <EOL> return encodepoint ( A ) <EOL> def Hint ( m ) : <EOL> h = H ( m ) <EOL> return sum ( <NUM_LIT:2> ** i * bit ( h , i ) for i in range ( <NUM_LIT:2> * b ) ) <EOL> def signature_unsafe ( m , sk , pk ) : <EOL> """<STR_LIT>""" <EOL> h = H ( sk ) <EOL> a = <NUM_LIT:2> ** ( b - <NUM_LIT:2> ) + sum ( <NUM_LIT:2> ** i * bit ( h , i ) for i in range ( <NUM_LIT:3> , b - <NUM_LIT:2> ) ) <EOL> r = Hint ( <EOL> intlist2bytes ( [ indexbytes ( h , j ) for j in range ( b // <NUM_LIT:8> , b // <NUM_LIT:4> ) ] ) + m <EOL> ) <EOL> R = scalarmult_B ( r ) <EOL> S = ( r + Hint ( encodepoint ( R ) + pk + m ) * a ) % l <EOL> return encodepoint ( R ) + encodeint ( S ) <EOL> def isoncurve ( P ) : <EOL> ( x , y , z , t ) = P <EOL> return ( z % q != <NUM_LIT:0> and <EOL> x * y % q == z * t % q and <EOL> ( y * y - x * x - z * z - d * t * t ) % q == <NUM_LIT:0> ) <EOL> def decodeint ( s ) : <EOL> return sum ( <NUM_LIT:2> ** i * bit ( s , i ) for i in range ( <NUM_LIT:0> , b ) ) <EOL> def decodepoint ( s ) : <EOL> y = sum ( <NUM_LIT:2> ** i * bit ( s , i ) for i in range ( <NUM_LIT:0> , b - <NUM_LIT:1> ) ) <EOL> x = xrecover ( y ) <EOL> if x & <NUM_LIT:1> != bit ( s , b - <NUM_LIT:1> ) : <EOL> x = q - x <EOL> P = ( x , y , <NUM_LIT:1> , ( x * y ) % q ) <EOL> if not isoncurve ( P ) : <EOL> raise ValueError ( "<STR_LIT>" ) <EOL> return P <EOL> class SignatureMismatch ( Exception ) : <EOL> pass <EOL> def checkvalid ( s , m , pk ) : <EOL> """<STR_LIT>""" <EOL> if len ( s ) != b // <NUM_LIT:4> : <EOL> raise ValueError ( "<STR_LIT>" ) <EOL> if len ( pk ) != b // <NUM_LIT:8> : <EOL> raise ValueError ( "<STR_LIT>" ) <EOL> R = decodepoint ( s [ : b // <NUM_LIT:8> ] ) <EOL> A = decodepoint ( pk ) <EOL> S = decodeint ( s [ b // <NUM_LIT:8> : b // <NUM_LIT:4> ] ) <EOL> h = Hint ( encodepoint ( R ) + pk + m ) <EOL> ( x1 , y1 , z1 , t1 ) = P = scalarmult_B ( S ) <EOL> ( x2 , y2 , z2 , t2 ) = Q = edwards_add ( R , scalarmult ( A , h ) ) <EOL> if ( not isoncurve ( P ) or not isoncurve ( Q ) or <EOL> ( x1 * z2 - x2 * z1 ) % q != <NUM_LIT:0> or ( y1 * z2 - y2 * z1 ) % q != <NUM_LIT:0> ) : <EOL> raise SignatureMismatch ( "<STR_LIT>" ) </s>
