Precompiled-Contracts

對模冪預編譯合約乘法的澄清

  • February 22, 2018

我試圖了解 Vitalik 在以下內容中的確切含義(來自此處):

請注意,不需要為加法和減法添加預編譯,因為 in-EVM 算法足夠高效,並且可以通過此預編譯通過a * b = ((a + b)**2 - (a - b)**2) / 4.

我的理解是,這是執行乘法的一種更有效的方式,但究竟要傳遞給 modexp 合約以實現乘法呢?是 (a+b) 和 (ab) 的平方嗎?在這種情況下,應該將什麼作為模值傳遞?

但是究竟要傳遞給 modexp 合約以實現乘法呢?是 (a+b) 和 (ab) 的平方嗎?

是的,正是這樣。

要計算a * b % m,您呼叫預編譯一次來計算(a+b)^2 % m,再呼叫一次來計算(a-b)^2 % m,然後取差值(m必要時添加以保持一切為正)。這給你4 * a * b % m

為了最終得到a * b % m,我們需要除以 4,取模m。做到這一點的“正確”方法是找到 4 的乘法倒數m並乘以它。這有點棘手,只有當 m 為奇數時才可能這樣做(即與 4 互質)。$$ But see note at the end $$

例子,證明4 * 5 % 7 = 6

(4 + 5)^2 % 7 = 4
(4 - 5)^2 % 7 = 1
4 - 1 = 3

所以我們有(4 * (4 * 5)) % 7 = 3. 模 7, 2 是 4 的倒數(因為(2 * 4) % 7 = 1)。因此,乘以 2 最終得到(4 * 5) % 7 = 6QED。

在這種情況下,應該作為模值傳遞什麼。

m與您傳入計算的相同(a * b) % m


筆記

要使用上面的普通模方法除以 4,我們需要乘以 4 的倒數,即模數m。這會給我們一個遞歸問題:進行乘法運算需要我們可以進行乘法運算。

但是,我認為有一個捷徑可以用來除以 4 模數m。我們除以 2 模數兩次m

  • 如果n是偶數(並且小於m),那麼n / 2 % m就是n / 2- 即右移一位。
  • 如果n是奇數,n / 2 % m可以簡單地通過計算(n + m) / 2 非模(加nm並右移一位)來找到。

所以,在上面的例子3 / 4 % 7中發現如下:

(3 + 7) / 2 = 5
(5 + 7) / 2 = 6

這與我們之前通過乘以 4 對 7(即 2)的倒數得到的結果相同。

引用自:https://ethereum.stackexchange.com/questions/24274