Solidity
如何使用solidity驗證secp256r1簽名
抱歉,如果您發現這些問題很基本,但我是加密新手。據我所知,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 測試,這些測試應該有助於理解變數的格式。