[応用代数] ブール方程式を解くための 4 つの効率的なベースライン アルゴリズム

ブール方程式を解くための 4 つの効率的なベースライン アルゴリズム


ブール方程式を解くことは理論計算における基本的な問題の 1 つであり、実際にはF q \mathbb{F}_qを解くことになります。Fqnnn個の変数mmm非線形多項式は基本的な数学的問題であり、暗号コミュニティを含むさまざまな理論的なコンピューター研究の方向性から広範な注目を集めています。周知のとおり、AI 分野におけるコンピューター ビジョンと自然言語処理には、多くの特定のタスク (人間のタスクなど) があります。顔認識、セマンティック セグメンテーション) ベースライン (つまり、参照比較を提供するベースライン モデル/アルゴリズム)、ブール方程式を解くための自然研究にも対応するベースラインがあります。今日は、現時点で最も効率的なベースライン アルゴリズムを 4 つ紹介します。

ここに画像の説明を挿入

ブールPoSSo (多項式系の解法) 問題: 一連のブール多項式F \mathcal{F}が与えられた場合ファ

{ f 1 , f 2 , … , fm } ⊆ R 2 \{f_{1}, f_{2}, \ldots, f_{m}\} \subseteq \mathcal{R}_{2}{ f1f2fメートル}R2

目標は、解( x 1 , … , xn ) ∈ F 2 n (x_{1}, \ldots, x_{n}) \in \mathbb{F}_{2}^{n} を見つけることです。( ×1バツ)F2∀ fi ∈ F \forall f_ { i} \in \mathcal{F}∀f _私はF , 满十分fi ( x 1 , … , xn ) = 0 f_{i}(x_{1}, \ldots, x_{n})=0f私は( ×1バツ)=0 . そのうち:

R 2 = F 2 [ x 1 , … , xn ] / ⟨ x 1 2 + x 1 , x 2 2 + x 2 , ⋯ , xn 2 + xn ⟩ \mathcal{R}_{2}=\mathbb{F }_{2}[x_{1}, \ldots, x_{n}] / \langle x_{1}^{2}+x_{1}, x_{2}^{2}+x_{2}, \cdots、x_{n}^{2}+x_{n}\rangleR2=F2[ ×1バツ] / ×12+バツ1バツ22+バツ2バツn2+バツ

各変数の値もF 2 \mathbb{F}_{2}に制限されます。F2上長;


アルゴリズムの分類

ブール方程式を解く問題は、コンピュータ サイエンスにおける他の多くの NP 困難問題 (SAT 問題、MILP 整数計画問題など) に関連しているため、解のアイデアは探索解、代数的手法の 3 つのタイプに大別されます。この部門に従って、この記事では次の 4 つのベースライン アルゴリズムを紹介します。

  • BCS アルゴリズム(Boolean Characteristic Set Algorithm)[1]: 古典的な代数消去法Wu 消去法に基づく解法アルゴリズム。
  • Groebner 基底アルゴリズム[2]:多項式理想構築アルゴリズムGroebner Basisに基づく解法アルゴリズム(SAGE V9.2 の Polybol ライブラリに基づいて実装)。
  • FESLib ライブラリ(Fast Exhaustive Search Algorithm)[3]: 分割統治 + 解空間探索に基づく解法アルゴリズム (複雑さは指数関数レベルO ( d ⋅ 2 n ) \mathcal{O}(d \cdot 2^n)O ( d2n ));
  • Boolean Equations to SAT Algorithm (Boolean Equations to SAT Algorithm)[4]: ブール方程式の問題を同等の SAT 問題に変換し、SAT ソルバー (Cryptominisat に基づく) を使用してそれを解くアルゴリズム。

この記事では主に実装に焦点を当てます (すべてのコードは Linux でコンパイルおよび実装されます)。理論的な部分は参考文献に記載されています (必要に応じて、これら 4 つの作業の技術的な詳細を紹介する別のブログを書きます)。


BCS算法(Boolean Characteristic Set Algorithm)

BCS アルゴリズム [1] は、Wu の消去法に基づく特徴列の計算に基づいていますが、ブール多項式の加算特性を巧みに使用し、元の方法の多項式展開の問題を克服しています

R 2 \mathcal{R}_{2}R2擬似除算を実行します 擬似除算: 多項式を使用しますP 1 = I 1 x C + R 1 P_{1}=I_{1} x_{C}+R_{1}P1=1バツC+R1消去要素P 2 = I 2 xc + R 2 P_{2}=I_{2} x_{c}+R_{2}P2=2バツc+R2x_{C}のx CバツC. 計算します:

I 1 (I 2 x C + R 2 ) + I 2 (I 1 xc + R 1 ) = I 1 R 2 + I 2 R 1 I_{1}(I_{2} x_{C}+R_{2} )+I_{2}(I_{1} x_{c}+R_{1})=I_{1} R_{2}+I_{2} R_{1}1(2バツC+R2)+2(1バツc+R1)=1R2+2R1

其中 I 1 , I 2 , R 1 , R 2 I_{1},I_{2},R_{1},R_{2} 12R1R2どちらも多項式であるため、このような演算は多項式の次数と項数の急速な拡張につながります (このような拡張は消去のたびに発生します)。

本稿における消去法の多項式展開を防ぐ方法は、主に次の 2 点に基づいています。

  • 零点分解,作情况分支:
    V ⁡ ( F , I x c + U ) = V ⁡ ( F , x c + U , I + 1 ) ∪ V ⁡ ( F , U , I ) \operatorname{V}(\mathcal{F}, I x_{c}+U)=\operatorname{V}(\mathcal{F}, x_{c}+U, I+1) \cup \operatorname{V}(\mathcal{F},U, I) V ( F ,私は×c+=V ( F ,バツc++1 )V ( F ,

  • F 2 \mathbb{F}_{2}F2 上加法消元: ( x c + U 1 ) + ( x c + U 2 ) = U 1 + U 2 (x_{c}+U_{1})+(x_{c}+U_{2})=U_{1}+U_{2} ( ×c+U1)+( ×c+U2)=U1+U2

より具体的なアルゴリズムについては、原文を参照してください。コードの実装は以下に示されています (ソース コード: https://github.com/hzy-cas/BCS)。アルゴリズムの実装は主に CUDD パッケージに依存します。ブール関数を表す二項決定を実装します グラフ データ構造 BDD (二項決定図) とそれに対応するアルゴリズムは、初期式を選択するとき、CUDD パッケージのコンパイル (cudd-2.4.2 を使用) の方が高速になります。

1 つ目は、Makefile 内の XCFLAGS を変更することです (ホストの gcc バージョンに対応します)。

XCFLAGS	= -mtune=native -DHAVE_IEEE_754 -DBSD -DSIZEOF_VOID_P=8 -DSIZEOF_LONG=8

次に、make がありますが、make install はありません。その後の依存関係のコンパイルは手動パスです。以下は、BCS アルゴリズムのコードをコンパイルするための Makefile です (コンパイルされた cudd は「/download/my_install/cudd-」に配置されます)。 2.4.2インチ):

CFILES = main.cpp
INSTALL_DIR = /download/my_install/cudd-2.4.2
INCLUDING_PATH = /download/my_install/cudd-2.4.2/include
OBJFILES = main.o binary.o IO.o zddrcs.o zddrp.o zddrps.o zddrpss.o
CFLAGS = -pg
CFLAGS = -g -I$(INCLUDING_PATH) -L$(INSTALL_DIR)/cudd -L$(INSTALL_DIR)/epd -L$(INSTALL_DIR)/mtr -L$(INSTALL_DIR)/st -L$(INSTALL_DIR)/util
CC = g++
LIBS = -lcudd -lmtr -lst -lutil -lepd
DDDEBUG = -DDD_STATS

wu_char: main.o binary.o IO.o zddrcs.o zddrp.o zddrps.o zddrpss.o 
	$(CC) -o wu_char $(CFLAGS) $(OBJFILES) $(LIBS)

binary.o: binary.cpp 
	$(CC) -c $(CFLAGS) binary.cpp

IO.o: IO.cpp 
	$(CC) -c $(CFLAGS) IO.cpp

zddrcs.o: zddrcs.cpp 
	$(CC) -c $(CFLAGS) zddrcs.cpp

zddrp.o: zddrp.cpp 
	$(CC) -c $(CFLAGS) zddrp.cpp

zddrps.o: zddrps.cpp 
	$(CC) -c $(CFLAGS) zddrps.cpp

zddrpss.o: zddrpss.cpp 
	$(CC) -c $(CFLAGS) zddrpss.cpp

main.o: main.cpp 
	$(CC) -c $(CFLAGS) main.cpp

clean: 
	\rm -f $(OBJFILES)

BCS アルゴリズムを使用して変数n = 16 n=16を解きます。n=1 6二次ブール方程式:

[hanss@Mint]$ ./wu_char
--------------BCS algorithm by Zhenyu Huang, Version 1.2----------------
Please choose the RUNNING MODE:
0 for PoSSo mode(obtian all solutions );
1 for SAT mode (obtain one monic triangular set);
2 for Counting mode (Counting zero number);
0
-----------------Solving Mode: Obtain all solutions-------------------
Please input the name of the file containing the input polynomial system:
n16m32.poly
... ...
x1+1,x2+1,x3,x4+1,x5,x6+1,x7,x8,x9+1,x10+1,x11,x12+1,x13,x14,x15,x16

ここで、「x1+1」はx 1 = 1 x_1 = 1を意味します。バツ1=1 、「x3」は x 3 = 0 x_3 = 0を表します。バツ3=0など。


グレブナー基底アルゴリズム (SageMath V9.2 の PolyBori)

定義 (グレブナー基底):多項式群G ⊂ K [ x 1 . . . xn ] \mathbb{G} \subset \mathcal{K}[x_1...x_n]GK [ ×1バツ]は、正規形nform ⁡ ( G , G ) \operatorname{nform}(G, \mathbb{G})n形式( G , _ _ _G )すべてのG ∈ K [ x 1 . . . xn ] G \in \mathcal{K}[x_1...x_n]についてGK [ ×1バツ]はユニークです。SayG \mathbb{G}Gは多項式群P ⊂ K [ x 1 . . . xn ] \mathbb{P} \subset \mathcal{K}[x_1...x_n]PK [ ×1バツ]または理想⟨ P ⟩ \langle\mathbb{P}\ranglePのグレブナー基底 ( G \mathbb{G}の場合Gはグレブナー基底であり、⟨ P ⟩ = ⟨ G ⟩ \langle\mathbb{P}\rangle=\langle\mathbb{G}\rangle⟨P⟩ _ _=⟨G⟩ _ _

すべてのイデアルには、有限個の多項式で構成されるグレブナー基底があります。これは、次のヒルベルト基底定理によって保証されます (すべての多項式イデアルJ ⊆ K [ x 1 . . . xn ] \mathcal{J} \subseteq \ mathcal{K}[x_1 ...x_n]JK [ ×1バツ]は有限に生成されます). 理想的な還元グレブナー基底 (特定の条件を付けたグレブナー基底) はある意味で一意であることが後でわかります. したがって、理想的なグレブナー基底を指す場合、通常は常に と考えられます。そして、グレブナーは基本的に良好な特性を備えたイデアルです (削減/消去/理想的なメンバーシップの決定に適しています)。

グレブナー基底アルゴリズムを使用して多項式を解くことは、基本的に元の多項式の消去イデアル、つまり消去イデアルI l I_{l}を求めることです。次のように定義されます。

I l = ⟨ f 1 , … , fs ⟩ ∩ k [ xl + 1 , … , xn ] I_{l}=\langle f_{1}, \ldots, f_{s}\rangle \cap k[x_{l +1}、\ldots、x_{n}]=f1fsk [ xl + 1バツ

それは、x 1 . . . xl x_1...x_lを意味します。バツ1バツ多項方程式系から多項式が削除されている場合、プロセスが単一の変数に進むと方程式が解かれます。

SageMath V9.2 の PolyBori の実現に基づいて、解決変数の数n = 16 n=16n=1 6二次ブール方程式 (完全なコード):

from sage.sat.converters.polybori import CNFEncoder
from sage.sat.solvers.dimacs import DIMACS

BOOLEAN_RING.<p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22,p23,p24,p25,p26,p27,p28,p29,p30,p31,p32,p33,p34,p35,p36,p37,p38,p39,p40> = BooleanPolynomialRing()
ITEMS_BOOLEAN = [p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22,p23,p24,p25,p26,p27,p28,p29,p30,p31,p32,p33,p34,p35,p36,p37,p38,p39,p40];

EQUATIONS_MQ = mq_coeff_2_poly(SAVED_PATH + "/mq_eqs_"+str(1)+".coeff",ITEMS_MQ + [1]);

IDEAL_MAIN = ideal(EQUATIONS_MQ);
GB_MAIN = IDEAL_MAIN.groebner_basis();
print_equations(GB_MAIN);

解の結果と意味は BCS アルゴリズムと同じです。

GB_MAIN = [p1 + 1,p2,p3 + 1,p4,p5 + 1,p6,p7 + 1,p8,p9 + 1,p10 + 1,p11 + 1,p12,p13 + 1,p14,p15,p16];

SAT アルゴリズムへ (SAT アルゴリズムへのブール方程式)

F 2 \mathbb{F}_2を解くF2最後の 2 次多変量方程式 (MQ 問題) は NP 困難です。もう 1 つの NP 困難問題は、論理式充足可能性問題 (SAT 問題) です。すべての NP 完全問題は多項式で約定できるため、MQ 問題の解は次のようになります。 SAT 問題の効果的な解決ツール (SAT ソルバーなど) を使用して見つけられます。

例(ブール方程式と命題論理式の変換): ブール方程式a ⊕ b ⊕ c = 0 a \oplus b \oplus c = 0あるbc=0は、次の等価な命題論理積のセットに変換できます。正規形の式はすべて true です。

a ∨ b ˉ ∨ c ˉ ( 1 ) a ˉ ∨ b ˉ ∨ c ( 2 ) a ∨ b ∨ c ( 3 ) a ˉ ∨ b ∨ c ˉ ( 4 ) \begin{array}{lll}a \vee \ bar{b} \vee \bar{c} & (1) & \bar{a} \vee \bar{b} \vee c & (2)\\ a \vee b \vee c & (3) & \ bar{a} \vee b \vee \bar{c} & (4 )\end{array}あるbˉcˉあるbc( 1 )( 3 )あるˉbˉcあるˉbcˉ( 2 )( 4 )

比如 a = a= ある= true およびb = b=b= true、つまり節 (2) を true にするには、 c = c= という事実が得られます。c=満たされる場合は true 同様に、a = a=ある= false、b = b=b= true およびc = c=c= true、元のブール方程式は満たされますが、節 (1) が矛盾を生じ、偽となります。

したがって、ブール方程式 (代数正規形 (ANF)) を命題論理積正規形 (CNF) に変換し、SAT ソルバーで解くことが変換ソリューションになります。実装は次のとおりです (完全なコード)

from sage.sat.converters.polybori import CNFEncoder
from sage.sat.solvers.dimacs import DIMACS

# --- 变元声明 ---
BOOLEAN_RING.<p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22,p23,p24,p25,p26,p27,p28,p29,p30,p31,p32,p33,p34,p35,p36,p37,p38,p39,p40> = BooleanPolynomialRing()
ITEMS_BOOLEAN = [p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22,p23,p24,p25,p26,p27,p28,p29,p30,p31,p32,p33,p34,p35,p36,p37,p38,p39,p40];

# --- 读取布尔方程组 ---
EQUATIONS_MQ = mq_coeff_2_poly(SAVED_PATH + "/mq_eqs_"+str(1)+".coeff",ITEMS_MQ + [1]);

# --- ANF转换为CNF表达式并存储为.cnf文件 ---
TMP_FILE   = tmp_filename();
SAT_SOLVER = DIMACS(filename=TMP_FILE);
ANF2CNF_ENC = CNFEncoder(SAT_SOLVER, BOOLEAN_RING);
for POLYNOMIAL in EQUATIONS_MQ:
    ANF2CNF_ENC.clauses_dense(POLYNOMIAL);
WRITED_FILE = SAT_SOLVER.write();
WRITED_FILE = open("baseline_cryptominisat.cnf",'w');
print(open(TMP_FILE).read(),flush=True,file=WRITED_FILE);

# --- 调用 cryptominisat 求解 ---
os.system('cryptominisat5 --verb 0 baseline_cryptominisat.cnf');

問題を解くn = 8 n=8n=8 つのおもちゃレベルのブール方程式。SAT に変換する過程で、多項式をカットする必要があるため、多項式レベルの複雑さを持ついくつかの新しい変数が追加されます。たとえば、解の結果では、「44」は x 44 = を表します。 1 x_{44} =1バツ4 4=1、「-41」はx 41 = 0 x_{41}=0バツ4 1=0など:

[hanss@Mint]$ /App/SageMath/SageMath/sage baseline_cryptominisat.sage
s SATISFIABLE
v 1 -2 3 4 5 -6 7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 
v -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 42 43 
v 44 45 -46 -47 -48 -49 -50 51 52 -53 54 55 56 -57 -58 59 -60 -61 -62 -63 64 
v -65 66 -67 68 -69 -70 -71 -72 -73 -74 -75 76 77 -78 -79 -80 81 82 -83 -84 -85 
v -86 -87 -88 -89 90 -91 -92 93 94 95 -96 97 98 -99 100 101 102 -103 104 -105 
v 106 -107 108 109 110 111 -112 113 114 -115 -116 -117 118 119 -120 -121 -122 
v 123 124 125 -126 127 -128 129 130 131 132 -133 -134 135 -136 -137 -138 -139 
v 140 141 -142 143 144 145 -146 147 148 149 -150 -151 152 153 0
[Finished in 4.0s]

解空間検索(高速全数検索アルゴリズム)に基づくFESLibライブラリ

この作業では、最初にF 2 \mathbb{F}_{2}を定義します。F2導出の概念 (これにより、ビット演算の数が効果的に削減され、解の反復プロセス中の検索が高速化されます):

定義 ( F 2 \mathbb{F}_{2}の導関数)F2) : F 2 \mathbb{F}_{2}としますF2上記はiiに相当します。i 個の変数∂ f ∂ i \frac{\partial f}{\partial i}∂f _for x ↦ f ( x + ei ) + f ( x ) \mathbf{x} \mapsto f(\mathbf{x}+e_{i})+f(\mathbf{x})バツf ( x+e私は)+f ( x ) . 次に、任意の解ベクトルx \mathbf{x}x、次のものを持っています:

f ( x + ei ) = f ( x ) + ∂ f ∂ i ( x ) f(\mathbf{x}+e_{i})=f(\mathbf{x})+\frac{\partial f}{ \partial i}(\mathbf{x})f ( x+e私は)=f ( x )+∂f _( × )

其中 e i e_{i} e私はii _iビットが 1 である解ベクトル (ワンホット ベクトル)、解空間探索の初期化演算 INIT() と反復演算 NEXT() は次のように形式化できます。

ここに画像の説明を挿入
FESlib のコンパイルは少し複雑なので、CMakeLists.txt ファイルを書き直して Makefile ファイルを生成しました。

cmake_minimum_required(VERSION 3.10)

project(feslite VERSION 1.0 
	LANGUAGES C ASM)

include(CTest)

if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
  message(STATUS "Setting build type to 'Debug' as none was specified.")
  set(CMAKE_BUILD_TYPE "Debug" CACHE STRING "Choose the type of build." FORCE)
endif()

add_compile_options(-Wall -Werror -O3 -Wno-unused-function)

set(CMAKE_C_STANDARD 99)
set(CMAKE_C_STANDARD_REQUIRED True)

find_package(OpenMP)

if (DEFINED ENV{NO_SSE})
    message(STATUS "As per $NO_SSE, disabling all simd intrinsics")
else()
    include("config/sse2.cmake")
    include("config/avx2.cmake")
    include("config/avx512.cmake")
endif()
if (DEFINED ENV{NO_NEON})
    message(STATUS "As per $NO_NEON, disabling all ARM NEON intrinsics")
else()
    include("config/neon.cmake")
endif()

configure_file(src/feslite-config.h.in src/feslite-config.h)

add_subdirectory(src)
add_subdirectory(benchmark)

if(BUILD_TESTING)
  add_subdirectory(test)
endif()

make プロセス中に、ソース コードにコマンド「#pragma GCC unroll 64」を含むファイルのエラーが報告されました。これはサイクルを高速化するためのコマンドです。ホスト システムに関連している可能性があるため、実行できるのはキャンセルされる:

[hanss@Mint]$ sed "s/#pragma GCC unroll 64/\/\/#pragma GCC unroll 64/g" -i ./src/*.c

それからもう一度作成して、それを使って変数n = 36 n=36を解く方法に焦点を当てましょう。n=3 6ブール方程式 (重要な部分についてコメントしました。完全なコード):

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "feslite.h"
#include "cycleclock.h"

int main()
{
    
    
    int n = 32; // num of variables;
    int k = 32; // num of quadratic boolean equations;
    int m = 16;

    /* Reading Numbers from File */
    u32 Fq[496]; // Quadratic terms num = C(2,32); Think about why not 496*m?? The fact is that any two systems in m systems have the same quadratic terms(which can be veritified by computing examples);
    u32 Fl[33 * m]; // Linear terms num = num of variables + 1;
    // === Reading The Equations from file fq_and_fl_array.dat ===
    FILE *FILE_IO_COUNT,*FILE_IO_READ;char TMP_CHAR;char NUM_CHAR[20];char READ_CHAR[20];int TMP_NUM;
    FILE_IO_COUNT = fopen("fq_and_fl_array.dat","r");FILE_IO_READ = fopen("fq_and_fl_array.dat","r");
    for (int INDEX_i = 0; INDEX_i < 496; ++INDEX_i)
    {
    
    
        int COUNT_BIT = 0;TMP_CHAR = fgetc(FILE_IO_COUNT);
        while(TMP_CHAR != ','){
    
    COUNT_BIT++;TMP_CHAR = fgetc(FILE_IO_COUNT);}
        fgets(NUM_CHAR, COUNT_BIT+1, FILE_IO_READ);
        fgets(READ_CHAR, 2, FILE_IO_READ);
        Fq[INDEX_i] = char2u32(NUM_CHAR);
    }
    for (int INDEX_i = 0; INDEX_i < 33*m; ++INDEX_i)
    {
    
    
        int COUNT_BIT = 0;TMP_CHAR = fgetc(FILE_IO_COUNT);
        while(TMP_CHAR != ','){
    
    COUNT_BIT++;TMP_CHAR = fgetc(FILE_IO_COUNT);}
        fgets(NUM_CHAR, COUNT_BIT+1, FILE_IO_READ);
        fgets(READ_CHAR, 2, FILE_IO_READ);
        Fl[INDEX_i] = char2u32(NUM_CHAR);
    }
    // === Reading End ===

    /* solve */
    u32 solutions[256 * m]; // Stored solutions;
    int size[m]; // Record how many solutions can be found of each system;
    uint64_t start = Now(); // Record the start time;
    feslite_solve(n, m, Fq, Fl, 256, solutions, size); // Solving m systems once;
    uint64_t stop = Now(); // Record the stop time;

    /* report */
    int kernel = feslite_default_kernel(); // Solver kernel;
    const char *name = feslite_kernel_name(kernel); // Which kernel used;
    printf("%s : %d lanes, %.2f cycles/candidate\n", 
        name, m, ((double) (stop - start)) / m / (1ll << n)); // Print time cost;
    for (int i = 0; i < m; i++)
    printf("Lane %d : %d solutions found\n", i, size[i]); // Print solving results;
    return EXIT_SUCCESS; // Ending;
}

ここで、ソース コードを見るといつも疑問に思うのですが、これではF 2 \mathbb{F}_{2}が解決されていません。F2上記の方程式の場合、係数配列 Fq[] と Fl[] の型が符号なし 32 ビット整数 u32 であるのはなぜですか?? そこで、著者に問い合わせるために電子メールを送信したところ、著者は次のように答えました。

ここで説明します。
Fl[0] には定数項が含まれます。
Fl[i + 1] には線形単項式 x_i の係数が含まれます (変数は x_0, …, x_{n-1})。
Fq[idxq(i,j)] には、i < j の 2 次単項式 x_i*x_j の係数が含まれます。関数 idxq() は fes.h で定義されています
。 さて、これらの係数はすべて実際に 0/1 です。秘訣は、32 個の方程式があり、コードが「ビットスライス」を使用していることです。32 ビット ワードの単一配列を使用して 32 の方程式を表します。Fl[0] の j 番目のビットには、j 番目の方程式の定数項が含まれています。Fl[i+1] の j 番目のビットには、j 番目の方程式の x_i の係数が含まれます。したがって、ステートメントは次のようになります。
k
Fq[i] = lrand48() & ((1ll << k) - 1);
個の連立方程式の 2 次単モアルの係数をランダムに初期化します。

素晴らしいです。つまり、少しカットされています。u32 整数は、実際には、方程式系全体で決定された項目順序に基づく同じ項目のすべての係数を表します。ここで、説明するために図を描きます。

ここに画像の説明を挿入
ここで、まだ疑問が残っています。つまり、メインのソルバー関数は、解くことができる方程式変数の上限をn = 32 n=32に制限しているということです。n=3 2、より大きな方程式を解く必要がある場合はどうすればよいでしょうか?

feslite_solve(n, m, Fq, Fl, 256, solutions, size);

その後、論文ではn = 36 n=36 を解くなどの単純な分割統治戦略が使用されていたことが判明しました。n=3 6方程式、走査x 33 , . . . , x 36 x_{33},...,x_{36}バツ3 3バツ3 6とすると、元の方程式はm = 2 4 m = 2^4に分岐できます。メートル=24 n = 32 n =32n=3 2スケール方程式、これはインターフェイス関数の m の意味でもあります (分岐と sage コードの .dat ファイルへの書き込みに関する完全なコードを参照してください); その後、コンパイルして実行します。

[hanss@Mint]$ gcc solver_n40.c -o exe -I/download/my_install/libfes-lite-10years/src -L/download/my_install/libfes-lite-10years/build/src -lfeslite
[hanss@Mint]$ ./exe
avx2_16x16 : 16 lanes, 0.06 cycles/candidate
Lane 0 : 0 solutions found
... ...
Lane 15 : 1 solutions found

参考文献

[1] Zhenyu Huang、Yao Sun、Dongdai Lin、特性集合法によるブール多項式システムの解決の効率について、Journal of Symbolic Computation、2019。 [2] Michael Brickenstein および Alexander Dreyer、PolyBoRi: グレブナー基準のフレーム
ワークブール多項式を使用した計算、Journal of Symbolic Computation、2009 年。
[3] Bouillaguet、Charles および Chen、Hsieh Chung および Cheng、Chen Mou および Chou、Tung および Yang、Bo ying、F2 における多項式システムの高速徹底的検索、暗号化ハードウェアおよび組み込みシステム、CHES 2010、第 12 回国際ワークショップ、サンタバーバラ、米国カリフォルニア州、2010 年 8 月 17 ~ 20 日。
[4] Soos M.、Nohl K.、Castelluccia C.: SAT ソルバーを暗号問題に拡張する。出典: Kullmann O.(編) 満足度テストの理論と応用 - SAT 2009。SAT 2009。コンピュータ サイエンスの講義ノート、vol 5584。Springer、ベルリン、ハイデルベルク、2009。

おすすめ

転載: blog.csdn.net/hanss2/article/details/124956384