Secret-Sharing

Shamir 秘密共享方案中的欄位大小是否應該大於秘密?

  • March 19, 2021

我正在嘗試在 Kotlin 中實施 Shamir 的秘密共享方案。

到目前為止,這是實現:

fun main(args: Array<String>) {

val a = 10.0.toBigDecimal()
val b = 10.0.toBigDecimal()
val c = 7.0.toBigDecimal() // secret
val field = 20.0.toBigDecimal()
fun polynomial() : (BigDecimal) -> BigDecimal =
   { x : BigDecimal -> ((a * x.pow(2))+(b*x)+c).remainder(field)}

fun generateShares(one :BigDecimal, two : BigDecimal, three :BigDecimal): List<Pair<BigDecimal,BigDecimal>> {
   var shareSet = arrayOf(one,two,three)
   return shareSet.map { x ->  Pair(x, polynomial().invoke(x)) }
}

val shares = generateShares(1.0.toBigDecimal(), 2.0.toBigDecimal(), 3.0.toBigDecimal())

fun langraged(cord0 : Pair<BigDecimal,BigDecimal>,cord1 : Pair<BigDecimal,BigDecimal>,cord2 : Pair<BigDecimal,BigDecimal>) : (BigDecimal, BigDecimal) -> BigDecimal{
   val L0: (BigDecimal) -> BigDecimal = { x -> ((x - cord1.first)*(x - cord2.first)) / ((cord0.first - cord1.first)*(cord0.first - cord2.first))}
   val L1: (BigDecimal) -> BigDecimal = { x -> ((x - cord0.first)*(x - cord2.first)) / ((cord1.first - cord0.first)*(cord1.first - cord2.first))}
   val L2: (BigDecimal) -> BigDecimal = { x -> ((x - cord0.first)*(x - cord1.first)) / ((cord2.first - cord0.first)*(cord2.first - cord1.first))}

   return { x, field -> // This lambda is what I am asking about
       val resser = cord0.second * L0(x) + cord1.second * L1(x)  + cord2.second * L2(x)
       if (resser < 0.0.toBigDecimal()){
           (resser % field) + field}
       else {
           resser % field
       }
   }
}

val constructedPolynomial = langraged(shares[0], shares[1], shares[2])

val reConstructedSecret = constructedPolynomial(0.0.toBigDecimal(), field)


println("and we reconstruct f(0) as: " + reConstructedSecret)

}

所以我的問題的要點是關於我的欄位大小的使用,我用於模數。

通過這個實現,如果我選擇一個大於我的秘密的欄位,那麼我將只能重建除以欄位大小後剩餘的秘密部分。

換句話說,為了重建我的多項式,當使用一個欄位時,我必須返回

result % field 

例如,如果我的欄位是 50,我的秘密是 51,那麼我重建的秘密是 1。

那麼,為了使用Shamir的方案和一個欄位,欄位是否必須大於我的秘密?還是我可以做一些技巧來重建它?

所以我的問題的要點是關於我的欄位大小的使用,我用於模數。

嗯,首先要注意的是“領域”的定義(這是一個數學術語);我不想討論什麼是欄位(如果您有興趣,請在 Wikipedia 中查找),但是以復合(例如 50)為模的加法和乘法不是欄位,Shamir Secret Sharing 贏了不在那里工作。

如果您將 50 替換為 53(這是素數),那麼它會起作用。

在實踐中,我們經常使用擴展欄位 $ GF(2^k) $ 為了 $ k $ 也許是 8 或 16 或 32;這使得事情很好地以字節排列,但是操作不是以欄位大小為模的(“加法”操作實際上是異或,乘法操作與您習慣的操作有很大不同)。當然,如果您想對此進行調查,則取決於您;你可能想先學習一個主要領域(這是你正在使用的)的基礎知識。

無論如何,要解決您的問題:

那麼,為了使用Shamir的方案和一個欄位,欄位是否必須大於我的秘密?還是我可以做一些技巧來重建它?

好吧,Shamir 的秘密共享的單次迭代將始終返回一個欄位元素(可以解釋為 0 和欄位大小減一之間的值);因此,如果您需要共享一個可能大於欄位大小的秘密,我們通常將秘密劃分為多個較小的秘密,並獨立共享每個子秘密。

例如,如果你有一個 16 字節的秘密,我們可以將它分成 16 個值,每個值一個字節;對於每個字節值,我們可以生成一個模 257(素數)的秘密多項式,並為此分配份額。當需要重構時,我們獨立地構造每個字節值,然後將它們連接起來形成原始的 16 字節秘密。

只是一個警告:您必須為每個字節生成一個獨立的秘密多項式 - 重複使用相同的多項式(常數項除外)會破壞系統。另一方面,您可以使用相同的 $ x $ 當您向某人分享時,協調每個子機密。

現在,與 $ p=257 $ ,每個共享將比原始秘密稍大(因為每個秘密共享是一個介於 0 和 256 之間的值;這不太適合一個字節)。這就是為什麼使用 $ GF(256) $ 很受歡迎;每個秘密份額都是一個介於 0 和 255 之間的值,所以一切都非常合適……

引用自:https://crypto.stackexchange.com/questions/88931