選択多項式

2022-06-01

  • AMRG 演算を一般化したらそうなった.
    • 暗号文から要素を選択するのでそう名付けた

線形変換は置換を表す?

  • ex. は置換にすると
  • では は?
  • 内積は に対し,
  • 置換では表現できない

演算を多項式表現する

定義(選択多項式)

暗号文の組 に対し, 演算をした結果は多変数多項式のベクトル で表される.

  • Add:
  • Mult:
  • Rotl:

命題

選択多項式 は1つ以上の選択多項式 の線形結合に分解出来る

定義(自明な分解)

選択多項式 は単位選択多項式(=1つだけの非零要素からなる1変数1次の選択多項式) の線形結合に出来る.

例:

分解と演算コスト

  • ex. の分解を考える.

自明な分解

ops: 2 add, 3 mult, 6rots

最適な分解

ops: 2 add, 1 mult, 3rots

最適な分解の構成の仕方について(WIP)

  • 多項式が与えられた時に最適な分解を探索するのは困難そう
    • 定式化をしてソルバで解くことは恐らく出来る
  • 自明な分解をしてからコストの低い結合をする?
  • 前ページの例のように0が含まれていると厄介

命題

置換 に対して置換行列 が決まるように, 多変多項式である選択多項式行列 に対しても置換マスク行列 がある

とりあえずソルバを使って最適解を求めてみる

  • 目的関数: 多項式ベクトルのコストだと思ったけど多項式から一意に決まらない -> 各演算に対応した単位行列?の分解に対してのコスト
    • 疎行列の分解に対応している?
    • マスク行列が重み, 定数項がバイアスと見ればperceptronの活性化関数ない版に見える気もする, 気のせいかも

問題

多変数多項式ベクトル が与えられた時に演算コストが最小になるような多変数多項式ベクトルの和の分解 を計算したい.

2022-05-30

  • 関連研究探し, 「vector of multivariate polynomial decomposition」とかで調べても全然出てこない. 多変数多項式を並べるということをしないらしい.
  • もう少し抽象化できれば数学のテーマとしてあるんだろうか? 全くわからない
  • https://www.jstage.jst.go.jp/article/sicetr1965/30/5/30_5_519/_pdf
    • 制御理論 の論文だが, 多変数多項式の行列で要素同士の共通因数みたいな話が出てきた. 少し近いかも しれない

まずは多項式が線形な場合のみ考える?.

定式化

,
選択多項式 の分解

ただし,

制約,

ソルバ実装

現状, 回転に対応していない, ベクトルから多項式にする.

  • Q: E-graphによる自明な分解から結合は可能? todo
a0 a1   b0 b1   a0 a1   b0 b3   
a2 a3 . b2 b3 = a3 a2 . b2 b1 + 

get_index

get_index(A: vec, i: uint) 
<=> A * mask({i}) << i

例: get_index(A, 1)

set_index

set_index(A: vec, i: usize, v: uint)
<=> (A * mask(inv({i})) + ((all(v) * mask({i})) >> i)

naive

rep i d
	rep j d
		rep k d
			c[i][j] += a[i][k] * b[k][j]
c

into dot-product

fn matmul (a b) =
	(rep i d
		(rep j d
			c[i][j] = a[Li] . b[Cj]
		)
	)

col

  • 行列としてみたとき, 列目を先頭 個に並べる
# cのk列目(=[d * i + k])を先頭d個(=[i])に並べる
fn col(v k) =
	(rep + i d
		rotl(v[d * i + k], (d * i + k - i))
	)

置換行列

  • 値が不要な所は0

ex. col(A, 1)

が定まり,

line

  • 行列の 行目を取得して先頭 個に並べる
line(A, k)
<=>
A * mask({ kd, ..., kd + d }) << kd

内積


fn dp (va vb) =
	(rep + i n
		(get_index va i) * (get_index vb i)
	)

行列積

fn matmul (a b) =
	let r = (const 0)
	(rep %i then d
		(rep %j then d
			let a_line_i = rotl(a .* mask(d * i, d * (i + 1)), d * i)
	        let b_col_j = col_vec(b, j)
			// r[i * d + j] = <a_i | b_j>
	        set_index(r, i * d + j, dp(a_line_i, b_col_j))
		)
	)
  • verified
  • ここで は単射より
    • <=>
      • 単射なのでマスクして回転する必要が無い位の意味

get_index(k) =
line(k) =
col(k) =

具体例:

写像で表す.

a = [1, 2, 3, 4], b = [5, 6, 7, 8]

naive

# (kd + i → i) . (id + k → i)
dp := line(i) . col(j) = [*, *, 0, 0]

# (0..d +→ 0)
dp_sum = sum_{d} dp << i = [*, *, 0, 0]
dp_sum_mask = dp_sum * mask(id + j) = [*, 0, 0, 0]

# (0 → id + j)
dp_sum_mask_rot = dp_sum_mask >> (id + j) = [0, *, 0, 0]
matmul(a, b)[id + j] = dp_sum_mask_rot

->lintrans

# (kd + i → i) . (id + k → i) devided by k
dp := line(i) . col(j) = [*, *, 0, 0]
dp_k=0 :=