Javascript elliptical point multiplication algorithm

故事扮演 提交于 2019-12-08 08:09:46

问题


The following is an implementation of elliptical curve Point Multiplication, but it's not working as expected (using recent Chrome / Node with BigInt for illustration):

const bi0 = BigInt(0)
const bi1 = BigInt(1)
const bi2 = BigInt(2)
const bi3 = BigInt(3)

const absMod = (n, p) => n < bi0 ? (n % p) + p : n % p

export function pointAdd (xp, yp, xq, yq, p) {
  const lambda = (yq - yp) / (xq - xp)
  const x = absMod(lambda ** bi2 - xp - xq, p)
  const y = absMod(lambda * (xp - x) - yp, p)
  return { x, y }
}

export function pointDouble (xp, yp, a, p) {
  const numer = bi3 * xp ** bi2 + a
  const denom = (bi2 * yp) ** (p - bi2)
  const lambda = (numer * denom) % p
  const x = absMod(lambda ** bi2 - bi2 * xp, p)
  const y = absMod(lambda * (xp - x) - yp, p)
  return { x, y }
}

export function pointMultiply (d, xp, yp, a, p) {
  const add = (xp, yp, { x, y }) => pointAdd(xp, yp, x, y, p)
  const double = (x, y) => pointDouble(x, y, a, p)
  const recur = ({ x, y }, n) => {
    if (n === bi0) { return { x: bi0, y: bi0 } }
    if (n === bi1) { return { x, y } }
    if (n % bi2 === bi1) { return add(x, y, recur({ x, y }, n - bi1)) }
    return recur(double(x, y), n / bi2)
  }
  return recur({ x: xp, y: yp }, d)
}

Given a known curve with properties, the above succeeds for points P2 - P5, but starts failing at P6 onwards:

const p = BigInt('17')
const a = BigInt('2')
const p1 = { x: BigInt(5), y: BigInt(1) }

const d = BigInt(6)
const p6 = pointMultiply(d, p1.x, p1.y, a, p)
p6.x === BigInt(16) // incorrect value of 8 was returned
p6.y === BigInt(13) // incorrect value of 14 was returned

The known curve has values:

P   X    Y
—————————— 
1   5    1
2   6    3
3  10    6
4   3    1
5   9   16
6  16   13
7   0    6
8  13    7
9   7    6
10  7   11

I'm not sure if I misunderstand the algorithm or I've made an error in the implementation.


回答1:


I don't know javascript very well, so the code confuses me. But ...

In function pointAdd, and everywhere else, "division" must be done mod p. You're evidently doing it correctly in pointDouble, but not in pointAdd. In pointAdd, use the same pattern: Instead of

const lambda = (yq - yp) / (xq - xp)

do

const numer = yq - yp
const denom = (xq - xp) ** (p - bi2)
const lambda = (numer * denom) % p

though I would think it would much clearer and less error prone to simply have a modular inverse function instead of computing Xp-2 everywhere you need it.



来源:https://stackoverflow.com/questions/53572911/javascript-elliptical-point-multiplication-algorithm

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!