bool TTPAttack::run( const TTPTuple& d ) { Word original_z = d.z; // Convert the tuples vector<ThLeftNormalForm> theTuple( d.WL.size()+d.WR.size() ); for ( int i=0;i<d.WL.size();i++) { theTuple[i] = ThLeftNormalForm( BraidGroup( N ) , d.WL[i] ); theTuple[i].setPower( theTuple[i].getPower() % 2 ); } for ( int i=0;i<d.WR.size();i++) { theTuple[i+d.WL.size()] = ThLeftNormalForm( BraidGroup( N ) , d.WR[i] ); theTuple[i+d.WL.size()].setPower( theTuple[i+d.WL.size()].getPower() % 2 ); } // execute attack // run LBA to restore delta values reduceDeltaLBA( theTuple ); // Test LBA bool DelatLBA_succ = true; for ( int i=0;i<d.WL.size();i++) { if ( shortenBraid(N,theTuple[i].getWord()*-d.WL[i]).length() > 0) DelatLBA_succ = false; // cout << "F"; // else // cout << "S"; } for ( int i=0;i<d.WR.size();i++) { if ( shortenBraid(N,theTuple[i+d.WL.size()].getWord()*-d.WR[i]).length() > 0) DelatLBA_succ = false; // cout << "F"; // else // cout << "S"; } if ( !DelatLBA_succ ) cout << "WARN!!! Delta LBA FAILED!" << endl; // return oneOfSSSReps( d.WL.size(), d.WR.size(), theTuple ); // TTPTuple red_T; //return simpleLBA(d.WL.size(), d.WR.size(), theTuple, original_z ); return LBA(d.WL.size(), d.WR.size(), theTuple, original_z ); }
pair< ThLeftNormalForm , ThLeftNormalForm > ThLeftNormalForm::cycle( ) const { if( theDecomposition.empty( ) ) return pair< ThLeftNormalForm , ThLeftNormalForm >( *this , ThLeftNormalForm( theRank ) ); ThLeftNormalForm result = *this; Permutation first = *(theDecomposition.begin( )); if( theOmegaPower%2!=0 ) first = first.flip( ); result.theDecomposition.push_back( first ); result.theDecomposition.pop_front( ); result.adjust( ); return pair< ThLeftNormalForm , ThLeftNormalForm >( result , ThLeftNormalForm(first) ); }
pair< ThLeftNormalForm , ThLeftNormalForm > ThLeftNormalForm::decycle( ) const { if( theDecomposition.empty( ) ) return pair< ThLeftNormalForm , ThLeftNormalForm >( *this , ThLeftNormalForm( theRank ) ); ThLeftNormalForm result = *this; Permutation last = *(--theDecomposition.end( )); if( theOmegaPower%2==0 ) result.theDecomposition.push_front( last ); else result.theDecomposition.push_front( last.flip( ) ); result.theDecomposition.pop_back( ); result.adjust( ); return pair< ThLeftNormalForm , ThLeftNormalForm >( result , -ThLeftNormalForm(last) ); }
pair< bool , ThLeftNormalForm > ThLeftNormalForm::areConjugate( const ThLeftNormalForm& rep ) const { NF pr1 = *this; reverse( pr1 ); ThRightNormalForm rightNF1 = pr1; NF pr2 = rep; reverse( pr2 ); ThRightNormalForm rightNF2 = pr2; pair< bool , ThRightNormalForm > res = rightNF1.areConjugate( rightNF2 ); NF conj = res.second; reverse( conj ); return pair< bool , ThLeftNormalForm >( res.first , -ThLeftNormalForm(conj) ); }
pair< bool , ThLeftNormalForm > ThLeftNormalForm::ussConstructionIteration( map< ThLeftNormalForm , pair< ThLeftNormalForm , int > >& uss_new1 , map< ThLeftNormalForm , pair< ThLeftNormalForm , int > >& uss_checked1 , const map< ThLeftNormalForm , pair< ThLeftNormalForm , int > >& uss_new2 , const map< ThLeftNormalForm , pair< ThLeftNormalForm , int > >& uss_checked2 ) const { const Permutation omega = Permutation::getHalfTwistPermutation( theRank ); const pair< ThLeftNormalForm , pair< ThLeftNormalForm , int > > pr = *uss_new1.begin( ); uss_checked1[pr.first] = pr.second; uss_new1.erase( uss_new1.begin( ) ); // 1. compute the set of simple summit conjugators set< pair< Permutation , bool > > conj = pr.first.getSimpleUltraConjugators( pr.second.second ); for( set< pair< Permutation , bool > > ::iterator it=conj.begin( ) ; it!=conj.end( ) ; ++it ) { // Conjugate the current element ThLeftNormalForm conj( (*it).first ); ThLeftNormalForm res = -conj * pr.first * conj; // Check if the element is new if( uss_new1.find( res )!=uss_new1.end( ) || uss_checked1.find( res )!=uss_checked1.end( ) ) continue; // Compute new conjugator ThLeftNormalForm new_conjugator = pr.second.first * conj; pair< bool , ThLeftNormalForm > traj_add_result = ussAddTrajectory( res , new_conjugator , uss_new1 , uss_checked1 , uss_new2 , uss_checked2 ); if( traj_add_result.first ) return traj_add_result; } return pair<bool,ThLeftNormalForm>( false , ThLeftNormalForm( theRank ) ); }
pair< bool , ThLeftNormalForm > ThLeftNormalForm::areConjugate_uss( const ThLeftNormalForm& rep , int time_sec_bound ) const { if( theRank!=rep.theRank ) return pair< bool , ThLeftNormalForm >( false , ThLeftNormalForm( theRank ) ); int init_time = time(0); // 1. find representative of SSS1 triple< ThLeftNormalForm , ThLeftNormalForm , int > tr1 = findUSSRepresentative( ); triple< ThLeftNormalForm , ThLeftNormalForm , int > tr2 = rep.findUSSRepresentative( ); // Infimum and supremum of nf1 and nf2 must be the same if( tr1.first.theOmegaPower !=tr2.first.theOmegaPower || tr1.first.theDecomposition.size( )!=tr2.first.theDecomposition.size( ) ) return pair< bool , ThLeftNormalForm >( false , ThLeftNormalForm( theRank ) ); // If nf1==nf2 then we are lucky and can stop if( tr1.first==tr2.first ) return pair< bool , ThLeftNormalForm >( true , tr2.second * -tr1.second ); // 3. construct ultra summit sets map< ThLeftNormalForm , pair< ThLeftNormalForm , int > > uss_new1; map< ThLeftNormalForm , pair< ThLeftNormalForm , int > > uss_checked1; map< ThLeftNormalForm , pair< ThLeftNormalForm , int > > uss_new2; map< ThLeftNormalForm , pair< ThLeftNormalForm , int > > uss_checked2; ussAddTrajectory( tr1.first , tr1.second , uss_new1 , uss_checked1 , uss_new2 , uss_checked2 ); pair< bool , ThLeftNormalForm > traj_add_result = ussAddTrajectory( tr2.first , tr2.second , uss_new2 , uss_checked2 , uss_new1 , uss_checked1 ); if( traj_add_result.first ) return pair< bool , ThLeftNormalForm >( true , -traj_add_result.second ); // uss_new1[tr1.first] = pair< ThLeftNormalForm , int >( tr1.second , tr1.third ); // uss_new2[tr2.first] = pair< ThLeftNormalForm , int >( tr2.second , tr2.third ); for( int i=0 ; i<1000000 && uss_new1.size( ) && uss_new2.size( ) ; ++i ) { // Check if we have time to proceed int cur_time = time(0); if( cur_time-init_time>time_sec_bound ) return pair< bool , ThLeftNormalForm >( false , ThLeftNormalForm( theRank ) ); pair< bool , ThLeftNormalForm > pr = ussConstructionIteration( uss_new1 , uss_checked1 , uss_new2 , uss_checked2 ); if( pr.first ) { // cout << "Size: " << uss_new1.size()+uss_checked1.size() << " - " << uss_new2.size()+uss_checked2.size() << endl; return pair< bool , ThLeftNormalForm >( true , pr.second ); } // Check if we have time to proceed cur_time = time(0); if( cur_time-init_time>time_sec_bound ) return pair< bool , ThLeftNormalForm >( false , ThLeftNormalForm( theRank ) ); pr = ussConstructionIteration( uss_new2 , uss_checked2 , uss_new1 , uss_checked1 ); if( pr.first ) { // cout << "Size: " << uss_new1.size()+uss_checked1.size() << " - " << uss_new2.size()+uss_checked2.size() << endl; return pair< bool , ThLeftNormalForm >( true , pr.second.inverse( ) ); } } return pair< bool , ThLeftNormalForm >( false , ThLeftNormalForm( theRank ) ); }