@cloudflare/zkp-ecdsa
Version:
zkp-ecdsa: A Typescript Implementation of ZKAttest
208 lines • 6.91 kB
JavaScript
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
import { fromBytes, posMod, rnd, serdeBigInt, toBytes, verifyPosRange } from '../bignum/big.js';
import { jsonMember, jsonObject, toJson } from 'typedjson';
export class Group {
constructor(name, p, order) {
this.p = p;
this.order = order;
this.name = name;
}
isCompatPoint(pt) {
if (!this.eq(pt.group)) {
throw new Error('points not compatible');
}
return true;
}
isCompatScalar(s) {
if (!this.eq(s.group)) {
throw new Error('scalar not compatible');
}
return true;
}
sizeFieldBytes() {
const bitSize = this.p.toString(2).length;
return Math.ceil(bitSize / 8);
}
eq(g) {
return this.name === g.name;
}
newScalar(s) {
return new Group.Scalar(this, s);
}
randomScalar() {
return this.newScalar(rnd(this.order));
}
deserializeScalar(a) {
const s = fromBytes(a);
verifyPosRange(s, this.order);
return this.newScalar(s);
}
}
__decorate([
jsonMember({ constructor: String, isRequired: true }),
__metadata("design:type", String)
], Group.prototype, "name", void 0);
(function (Group) {
var Scalar_1;
class Point {
isCompatPoint(pt) {
return this.group.isCompatPoint(pt);
}
isCompatScalar(s) {
return this.group.isCompatScalar(s);
}
static toStringCoords(coords) {
let s = '';
for (const { name, value } of coords) {
s += `${name}:0x${value.toString(16)}\n`;
}
return s;
}
sub(pt) {
return this.add(pt.neg());
}
dblmul(s1, p2, s2) {
this.isCompatScalar(s1);
this.isCompatScalar(s2);
this.isCompatPoint(p2);
const digits = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'], mult1 = new Map(), mult2 = new Map();
let curr1 = this.group.identity(), curr2 = p2.group.identity();
for (const digit of digits) {
mult1.set(digit, curr1);
mult2.set(digit, curr2);
curr1 = curr1.add(this);
curr2 = curr2.add(p2);
}
let k1 = s1.base16(), k2 = s2.base16();
if (k1.length < k2.length) {
k1 = k1.padStart(k2.length, '0');
}
if (k2.length < k1.length) {
k2 = k2.padStart(k1.length, '0');
}
let q = this.group.identity();
for (let i = 0; i < k1.length; i++) {
q = q.dbl();
q = q.dbl();
q = q.dbl();
q = q.dbl();
q = q.add(mult1.get(k1[i]));
q = q.add(mult2.get(k2[i]));
}
return q;
}
mul(s) {
this.isCompatScalar(s);
const k = s.base16();
let q = this.group.identity();
const digits = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'], mults = new Map();
let curr = this.group.identity();
for (const digit of digits) {
mults.set(digit, curr);
curr = curr.add(this);
}
for (const ki of k) {
q = q.dbl();
q = q.dbl();
q = q.dbl();
q = q.dbl();
q = q.add(mults.get(ki));
}
return q;
}
}
Group.Point = Point;
let Scalar = Scalar_1 = class Scalar {
constructor(group, s) {
this.group = group;
this.k = s ? posMod(s, group.order) : BigInt(0);
}
toString() {
this.reduce();
return '0x' + this.k.toString(16);
}
bits() {
this.reduce();
return this.k.toString(2);
}
base16() {
return this.k.toString(16);
}
eq(s) {
this.reduce();
s.reduce();
return this.group.eq(s.group) && this.k === s.k;
}
add(s) {
return new Scalar_1(this.group, this.k + s.k);
}
sub(s) {
return new Scalar_1(this.group, this.k - s.k);
}
mul(s) {
return new Scalar_1(this.group, this.k * s.k);
}
neg() {
return new Scalar_1(this.group, -this.k);
}
toBytes() {
this.reduce();
return toBytes(this.k, this.group.sizeFieldBytes());
}
isOne() {
return this.k === BigInt(1);
}
isZero() {
return this.k === BigInt(0);
}
cmp(s) {
if (this.k < s.k) {
return -1;
}
else if (this.k > s.k) {
return 1;
}
else {
return 0;
}
}
reduce() {
this.k = posMod(this.k, this.group.order);
}
};
__decorate([
jsonMember({ constructor: Group, isRequired: true }),
__metadata("design:type", Group)
], Scalar.prototype, "group", void 0);
__decorate([
jsonMember(serdeBigInt),
__metadata("design:type", BigInt)
], Scalar.prototype, "k", void 0);
Scalar = Scalar_1 = __decorate([
jsonObject({
beforeSerialization: 'reduce',
}),
toJson,
__metadata("design:paramtypes", [Group, BigInt])
], Scalar);
Group.Scalar = Scalar;
})(Group || (Group = {}));
export async function hashPoints(hashID, points) {
const bytesPoints = points.map((p) => p.toBytes()), size = bytesPoints.map((b) => b.length).reduce((sum, cur) => sum + cur), bytes = new Uint8Array(size);
let offset = 0;
for (const bP of bytesPoints) {
bytes.set(bP, offset);
offset += bP.length;
}
const buf = await crypto.subtle.digest(hashID, bytes), hash = new Uint8Array(buf);
return fromBytes(hash.slice(0, 10));
}
//# sourceMappingURL=group.js.map