- 1. 概述
- 2. 签名格式
-
[3. ECDSA Signature R S to ASN1 DER Encoding](#3-ecdsa-signature-rs-to-asn1-der-encoding) - 4. js sample code
1. 概述
Secp256k1 是指比特币中使用的 ECDSA(椭圆曲线数字签名算法)曲线的参数,并且在高效密码学标准(Certicom Research,http://www.secg.org/sec2-v2.pdf )中进行了定义。
Secp256k1 为基于 Fp 有限域上的椭圆曲线,由于其特殊构造的特殊性,其优化后的实现比其他曲线性能上可以特高 30%,有明显以下两个优点:
- 占用很少的带宽和存储资源,密钥的长度很短。
- 让所有的用户都可以使用同样的操作完成域运算。
2. 签名格式
Signarure(M) = (r,s)
3. ECDSA Signature R|S to ASN1 DER Encoding
0x30|b1|0x02|b2|r|0x02|b3|s
b1 = Length of remaining data,1-byte
b2 = Length of r,1-byte
b3 = Length of s,1-byte
e.g.
r|s =
6f0156091cbe912f2d5d1215cc3cd81c0963c8839b93af60e0921b61a19c5430 c71006dd93f3508c432daca21db0095f4b16542782b7986f48a5d0ae3c583d4
==>
304402206f0156091cbe912f2d5d1215cc3cd81c0963c8839b93af60e0921b61a19c543002200c71006dd93f3508c432daca21db0095f4b16542782b7986f48a5d0ae3c583d4
=>
30
44
02
20
6f0156091cbe912f2d5d1215cc3cd81c0963c8839b93af60e0921b61a19c5430
02
20
0c71006dd93f3508c432daca21db0095f4b16542782b7986f48a5d0ae3c583d4
注:rs 会有 padding
4. js sample code
var EC = require("elliptic").ec;
require("buffer");
// Create and initialize EC context
// (better do it once and reuse it)
var ec = new EC("secp256k1");
// Generate keys
var key = ec.genKeyPair();
// Sign the message's hash (input must be an array, or a hex-string)
var msgHash = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
var signature = key.sign(msgHash);
// Export DER encoded signature in Array
var derSign = signature.toDER();
console.log("derSign:" + Buffer.from(derSign).toString("hex"));
// Verify signature
console.log(key.verify(msgHash, derSign));
// CHECK WITH NO PRIVATE KEY
var pubPoint = key.getPublic();
var x = pubPoint.getX();
var y = pubPoint.getY();
// Public Key MUST be either:
// 1) '04' + hex string of x + hex string of y; or
// 2) object with two hex string properties (x and y); or
// 3) object with two buffer properties (x and y)
var pub = pubPoint.encode("hex"); // case 1
var pub = { x: x.toString("hex"), y: y.toString("hex") }; // case 2
var pub = { x: x.toBuffer(), y: y.toBuffer() }; // case 3
var pub = { x: x.toArrayLike(Buffer), y: y.toArrayLike(Buffer) }; // case 3
// Import public key
var key = ec.keyFromPublic(pub, "hex");
// Signature MUST be either:
// 1) DER-encoded signature as hex-string; or
// 2) DER-encoded signature as buffer; or
// 3) object with two hex-string properties (r and s); or
// 4) object with two buffer properties (r and s)
var signature = "3046022100..."; // case 1
var signature = new Buffer("..."); // case 2
var signature = { r: "b1fc...", s: "9c42..." }; // case 3
// Verify signature
console.log(key.verify(msgHash, signature));