mirror of
https://github.com/arnaucube/blindsecp256k1-js.git
synced 2026-02-07 03:16:43 +01:00
Using up to date libraries for EC and BigNumber
This commit is contained in:
97
src/index.ts
97
src/index.ts
@@ -1,71 +1,82 @@
|
||||
import { randomBytes } from 'crypto'
|
||||
import * as BigInteger from 'bigi'
|
||||
import { getCurveByName, Point } from 'ecurve'
|
||||
import * as BigNumber from 'bn.js'
|
||||
import { ec, curve } from 'elliptic'
|
||||
import { keccak256 } from "@ethersproject/keccak256"
|
||||
|
||||
const ecparams = getCurveByName('secp256k1')
|
||||
const G = ecparams.G
|
||||
const n = ecparams.n as BigInteger
|
||||
export type Point = curve.base.BasePoint
|
||||
export { BigNumber }
|
||||
|
||||
export { ecparams }
|
||||
const secp256k1 = new ec("secp256k1")
|
||||
const G: Point = secp256k1.g
|
||||
const n = secp256k1.n // as BigNumber
|
||||
|
||||
export type UserSecretData = { a: BigInteger, b: BigInteger, f: Point }
|
||||
export type UnblindedSignature = { s: BigInteger, f: Point }
|
||||
export const ecParams = { G, n }
|
||||
|
||||
export function newBigFromString(s: string) {
|
||||
let a = new BigInteger(null, null, null)
|
||||
a.fromString(s, null)
|
||||
return a
|
||||
export type UserSecretData = { a: BigNumber, b: BigNumber, f: Point }
|
||||
export type UnblindedSignature = { s: BigNumber, f: Point }
|
||||
|
||||
export function hashBigNumber(m: BigNumber) {
|
||||
const mHex = m.toString(16)
|
||||
|
||||
if (mHex.length % 2 == 0)
|
||||
return keccak256('0x' + mHex).slice(2) // Trim 0x
|
||||
else
|
||||
return keccak256('0x0' + mHex).slice(2) // Trim 0x
|
||||
}
|
||||
|
||||
export function bigNumberFromString(s: string) {
|
||||
return new BigNumber(s)
|
||||
}
|
||||
|
||||
function random(bytes: number) {
|
||||
let k: BigInteger
|
||||
let k: BigNumber
|
||||
do {
|
||||
k = BigInteger.fromByteArrayUnsigned(randomBytes(bytes)) as unknown as BigInteger
|
||||
k = new BigNumber(randomBytes(bytes))
|
||||
} while (k.toString() == "0" && k.gcd(n).toString() != "1")
|
||||
return k
|
||||
}
|
||||
|
||||
export function newKeyPair() {
|
||||
const sk = random(32)
|
||||
return { sk: sk, pk: G.multiply(sk) }
|
||||
return { sk: sk, pk: G.mul(sk) }
|
||||
}
|
||||
|
||||
export function newRequestParameters() {
|
||||
const k = random(32)
|
||||
return { k: k, signerR: G.multiply(k) }
|
||||
return { k: k, signerR: G.mul(k) }
|
||||
}
|
||||
|
||||
/**
|
||||
* Blinds the message for the signer R.
|
||||
* @param {BigInteger} m
|
||||
* @param {BigNumber} m
|
||||
* @param {Point} signerR
|
||||
* @returns {struct} {mBlinded: BigInteger, userSecretData: {a: BigInteger, b: BigInteger, f: Point}}
|
||||
* @returns {struct} {mBlinded: BigNumber, userSecretData: {a: BigNumber, b: BigNumber, f: Point}}
|
||||
*/
|
||||
export function blind(m: BigInteger, signerR: Point): { mBlinded: BigInteger, userSecretData: UserSecretData } {
|
||||
const u: UserSecretData = { a: BigInteger.ZERO as BigInteger, b: BigInteger.ZERO as BigInteger, f: G }
|
||||
export function blind(m: BigNumber, signerR: Point): { mBlinded: BigNumber, userSecretData: UserSecretData } {
|
||||
const u: UserSecretData = { a: new BigNumber(0), b: new BigNumber(0), f: G }
|
||||
u.a = random(32)
|
||||
u.b = random(32)
|
||||
|
||||
const aR = signerR.multiply(u.a)
|
||||
const bG = G.multiply(u.b)
|
||||
const aR = signerR.mul(u.a)
|
||||
const bG = G.mul(u.b)
|
||||
u.f = aR.add(bG)
|
||||
|
||||
const rx = u.f.affineX.mod(n)
|
||||
const rx = u.f.getX().mod(n)
|
||||
|
||||
const ainv = u.a.modInverse(n as unknown as number)
|
||||
const ainvrx = ainv.multiply(rx)
|
||||
const ainv = u.a.invm(n)
|
||||
const ainvrx = ainv.mul(rx)
|
||||
|
||||
const mHex = m.toString(16)
|
||||
const hHex = keccak256('0x' + mHex)
|
||||
const h = BigInteger.fromHex(hHex.slice(2))
|
||||
const mBlinded = ainvrx.multiply(h)
|
||||
// const mHex = m.toString(16)
|
||||
const hHex = hashBigNumber(m)
|
||||
|
||||
const h = new BigNumber(Buffer.from(hHex, "hex"))
|
||||
const mBlinded = ainvrx.mul(h)
|
||||
|
||||
return { mBlinded: mBlinded.mod(n), userSecretData: u }
|
||||
}
|
||||
|
||||
export function blindSign(sk: BigInteger, mBlinded: BigInteger, k: BigInteger): BigInteger {
|
||||
let sBlind = sk.multiply(mBlinded)
|
||||
export function blindSign(sk: BigNumber, mBlinded: BigNumber, k: BigNumber): BigNumber {
|
||||
let sBlind = sk.mul(mBlinded)
|
||||
sBlind = sBlind.add(k)
|
||||
return sBlind.mod(n)
|
||||
}
|
||||
@@ -76,27 +87,27 @@ export function blindSign(sk: BigInteger, mBlinded: BigInteger, k: BigInteger):
|
||||
* @param userSecretData
|
||||
* @returns unblinded signature
|
||||
*/
|
||||
export function unblind(sBlind: BigInteger, userSecretData: UserSecretData): UnblindedSignature {
|
||||
const s = userSecretData.a.multiply(sBlind).add(userSecretData.b)
|
||||
export function unblind(sBlind: BigNumber, userSecretData: UserSecretData): UnblindedSignature {
|
||||
const s = userSecretData.a.mul(sBlind).add(userSecretData.b)
|
||||
return { s: s.mod(n), f: userSecretData.f }
|
||||
}
|
||||
|
||||
export function verify(m: BigInteger, s: UnblindedSignature, q: Point) {
|
||||
const sG = G.multiply(s.s)
|
||||
export function verify(m: BigNumber, s: UnblindedSignature, q: Point) {
|
||||
const sG = G.mul(s.s)
|
||||
|
||||
const mHex = m.toString(16)
|
||||
const hHex = keccak256('0x' + mHex)
|
||||
const h = BigInteger.fromHex(hHex.slice(2))
|
||||
const hHex = hashBigNumber(m)
|
||||
|
||||
const h = new BigNumber(Buffer.from(hHex, "hex"))
|
||||
|
||||
const rx = s.f.affineX.mod(n)
|
||||
const rx = s.f.getX().mod(n)
|
||||
const right = s.f.add(
|
||||
q.multiply(
|
||||
rx.multiply(h)
|
||||
q.mul(
|
||||
rx.mul(h)
|
||||
)
|
||||
)
|
||||
|
||||
if ((sG.affineX.toString() == right.affineX.toString())
|
||||
&& (sG.affineY.toString() == right.affineY.toString())) {
|
||||
if ((sG.getX().toString() == right.getX().toString())
|
||||
&& (sG.getY().toString() == right.getY().toString())) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
|
||||
Reference in New Issue
Block a user