# sCrypt 合约中的椭圆曲线算法：第二部分

111 篇文章 3 订阅

eGCD算法定义如下：

### 实现

static function modInverseEGCD(int x, int n) : int {
// The following script already does modular reduction at the start so there's no
// need to normalize x before function call.
asm {
OP_2DUP OP_MOD OP_DUP OP_0 OP_LESSTHAN OP_IF OP_DUP OP_2 OP_PICK OP_ADD OP_ELSE OP_DUP OP_ENDIF OP_NIP OP_2 OP_ROLL OP_DROP
OP_DUP OP_TOALTSTACK OP_TOALTSTACK OP_TOALTSTACK
OP_1 OP_0 OP_1
loop(UB) {
OP_FROMALTSTACK OP_FROMALTSTACK OP_2DUP OP_DUP OP_IF OP_TUCK OP_MOD OP_TOALTSTACK OP_TOALTSTACK OP_DIV OP_MUL OP_SUB OP_TUCK OP_ELSE OP_TOALTSTACK OP_TOALTSTACK OP_DROP OP_DROP OP_ENDIF
}
OP_FROMALTSTACK OP_FROMALTSTACK OP_DROP OP_DROP OP_DROP OP_FROMALTSTACK OP_SWAP OP_NIP
}
}


### 计算循环的上限

k 位模数 n 的迭代次数上限可以使用以下等式导出：

，其中 phi 是黄金比例：

### 点加法

static function addPoints(Point p, Point q) : Point {
Point ret = {0, 0};

if (p.x == 0 && p.y == 0) {
// if P == inf -> P + Q = Q
ret = q;
} else if (q.x == 0 && q.y == 0) {
// if Q == inf -> P + Q = P
ret = p;
} else {
int lambda = 0;
if (p.x == q.x && p.y == q.y) {
lambda = (3 * p.x * p.x) * modInverseEGCD(2 * p.y, P);
} else {
lambda = (q.y - p.y) * modInverseEGCD(q.x - p.x, P);
}

int rx = modReduce(lambda * lambda - p.x - q.x, P);
int ry = modReduce(lambda * (p.x - rx) - p.y, P);

ret = {rx, ry};
}

return ret;
}


### 点加倍

static function doublePoint(Point p) : Point {
int lambda = (3 * p.x * p.x) * modInverseEGCD(2 * p.y, P);

int rx = modReduce(lambda * lambda - 2 * p.x, P);
int ry = modReduce(lambda * (p.x - rx) - p.y, P);

Point res = {rx, ry};
return res;
}


### 标量乘法

static function multByScalar(Point p, int m) : Point {
// Lowest bit to highest.
Point n = p;
Point q = {0, 0};

bytes mb =   reverseBytes(num2bin(m, S), S);
bytes mask = reverseBytes(num2bin(1, S), S);
bytes zero = reverseBytes(num2bin(0, S), S);

loop (256) : i {
if ((mb & (mask << i)) != zero) {
}

n = doublePoint(n);
}

return q;
}


### ECDSA 签名验证

static function verifySig(bytes m, Signature sig, Point pubKey) : bool {
Sha256 hash = hash256(m);
int hashInt = unpack(reverseBytes(hash, 32));

require(sig.r >= 1 && sig.r < n && sig.s >= 1 && sig.s < n);

int sInv = modInverseEGCD(sig.s, n);
int u1 = modReduce(hashInt * sInv, n);
int u2 = modReduce(sig.r * sInv, n);

Point U1 = multByScalar(G, u1);
Point U2 = multByScalar(pubKey, u2);

return sig.r == X.x;
}


• 0
点赞
• 0
收藏
觉得还不错? 一键收藏
• 打赏
• 0
评论
04-14 5348
03-08 1475
07-10 3906
11-28 1157
09-18 77
03-01 580
08-25 1177

### “相关推荐”对你有帮助么？

• 非常没帮助
• 没帮助
• 一般
• 有帮助
• 非常有帮助

sCrypt Web3应用开发

¥1 ¥2 ¥4 ¥6 ¥10 ¥20

1.余额是钱包充值的虚拟货币，按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载，可以购买VIP、付费专栏及课程。