Solidity

如何使用solidity驗證secp256r1簽名

  • February 6, 2019

抱歉,如果您發現這些問題很基本,但我是加密新手。據我所知,Solidity 具有ecrecover 此目的,但它使用secp256k1簽名。我打算使用它secp256r1。我在這個要點中使用了以下步驟來獲得r,s, an v values.

然後我應用了來自WIKIpedia的所有 secp256r1 驗證,如下所示

1. getting r,s, and v values. 
2. verify that r, s are integers in [1,n-1].
3. calculate the hashing of the message.
4. calculate w = s^-1 mod n
5. calculate the curve point (x1,y1) = u1 x G + u2 x Q

提示:ecadd 是添加我寫的點函式。ecmul是一個乘法函式,isPoint:檢查點是否在曲線中。

我的問題是,

1-我是否正確地寫了方程式的五個步驟;我不是第 4 步和第 5 步。您可以查看驗證功能的程式碼以獲取更多詳細資訊。

2-如果我想檢查驗證。我應該發送消息和簽名。我是否需要返回超過 True/False 以進行驗證。

// testing signature function
// getting r, s, and v values from signature.
// steps would be as follows
// 1. getting r,s, and v values.
function ectest(bytes32 hash, bytes sig) returns (bool) {
   bytes32 r;
   bytes32 s;
   uint8 v;

   if (sig.length != 65)
     return (false, 0);

   // The signature format is a compact form of:
   //   {bytes32 r}{bytes32 s}{uint8 v}
   // Compact means, uint8 is not padded to 32 bytes.
assembly {
   r := mload(add(sig, 32))
   s := mload(add(sig, 64))

   // Here we are loading the last 32 bytes. We exploit the fact that
   // 'mload' will pad with zeroes if we overread.
   // There is no 'mload8' to do this, but that would be nicer.
   v := byte(0, mload(add(sig, 96)))

   // Alternative solution:
   // 'byte' is not working due to the Solidity parser, so lets
   // use the second best option, 'and'
   // v := and(mload(add(sig, 65)), 255)
}

// albeit non-transactional signatures are not specified by the YP, one would expect it
// to match the YP range of [27, 28]

if (v < 27)
 v += 27;

if (v != 27 && v != 28)
   return (false, 0);

// 2. verify that r, s are integers in [1,n-1] using isPoint function
if(isPoint(r,s) == false)
{
 return (false, 0);
}


//3. calculate the hashing of the message
e = sha3(msg);

//4. let v be the leftmost bits of msg
// calculate above in the assembly code
// v



     //5. calculate w = s^-1 mod n
     w  = invmod(s,n);
     // u1 = v * w mod n
     u1 = (v * w) % n ;
     // u2 = r * w mod n
     u2 = (r * w) % n;

     //6. calculate the curve point (x1,y1) = u1 x G + u2 x Q
     (x3,y3)=  ecmul(gx,gy,u1);
     (x4,y4)= ecmul(gx,gy,u2);

     (x1,y1) = ecadd(x3,y3,x4,y4);
     //7. check the validation
     if (r == x1)
     {
       return (true);
     }
   }// end function

}

這是一個重要的問題,因為所有其他世界(移動設備、智能卡、HSM 等)都使用 secp256r1。

http://blog.enuma.io/update/2016/11/01/a-tale-of-two-curves-hardware-signing-for-ethereum.html上有一篇文章

但不幸的是,實際實現該功能的程式碼已經消失了。計劃從字節碼逆向工程,但這可能需要一些時間……

在https://github.com/tdrerup/elliptic-curve-solidity有一個 SECP256R1 / P256 / PRIME256V1 的純 Solidity 實現。

主要缺點可能是在 Solidity 中驗證非本地簽名相當昂貴。該 repo 包含一些 truffle 測試,這些測試應該有助於理解變數的格式。

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