UNPKG

@dedis/kyber

Version:

A typescript implementation of Kyber interfaces

186 lines (185 loc) 5.72 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); // tslint:disable:no-bitwise const bn_js_1 = __importDefault(require("bn.js")); const crypto_browserify_1 = require("crypto-browserify"); const elliptic_1 = require("elliptic"); const ec = new elliptic_1.eddsa("ed25519"); class Ed25519Point { constructor(X, Y, Z, T) { if (X instanceof Buffer) { X = new bn_js_1.default(X, 16, "le"); } if (Y instanceof Buffer) { Y = new bn_js_1.default(Y, 16, "le"); } if (Z instanceof Buffer) { Z = new bn_js_1.default(Z, 16, "le"); } if (T instanceof Buffer) { T = new bn_js_1.default(T, 16, "le"); } // the point reference is stored in a Point reference to make set() // consistent. this.ref = { point: ec.curve.point(X, Y, Z, T), }; } /** @inheritdoc */ null() { this.ref.point = ec.curve.point(0, 1, 1, 0); return this; } /** @inheritdoc */ base() { this.ref.point = ec.curve.point(ec.curve.g.getX(), ec.curve.g.getY()); return this; } /** @inheritdoc */ pick(callback) { return this.embed(Buffer.from([]), callback); } /** @inheritdoc */ set(p) { this.ref = p.ref; return this; } /** @inheritdoc */ clone() { const { point } = this.ref; return new Ed25519Point(point.x, point.y, point.z, point.t); } /** @inheritdoc */ embedLen() { // Reserve the most-significant 8 bits for pseudo-randomness. // Reserve the least-significant 8 bits for embedded data length. // (Hopefully it's unlikely we'll need >=2048-bit curves soon.) return Math.floor((255 - 8 - 8) / 8); } /** @inheritdoc */ embed(data, callback) { let dl = this.embedLen(); if (data.length > dl) { throw new Error("data.length > embedLen"); } if (dl > data.length) { dl = data.length; } callback = callback || crypto_browserify_1.randomBytes; const pointObj = new Ed25519Point(); while (true) { const buff = callback(32); if (dl > 0) { buff[0] = dl; // encode length in lower 8 bits data.copy(buff, 1); // copy data into buff starting from the 2nd position } try { pointObj.unmarshalBinary(buff); } catch (e) { continue; // try again } if (dl === 0) { pointObj.ref.point = pointObj.ref.point.mul(new bn_js_1.default(8)); if (pointObj.ref.point.isInfinity()) { continue; // unlucky } return pointObj; } const q = pointObj.clone(); q.ref.point = q.ref.point.mul(ec.curve.n); if (q.ref.point.isInfinity()) { return pointObj; } } } /** @inheritdoc */ data() { const bytes = this.marshalBinary(); const dl = bytes[0]; if (dl > this.embedLen()) { throw new Error("invalid embedded data length"); } return bytes.slice(1, dl + 1); } /** @inheritdoc */ add(p1, p2) { const point = p1.ref.point; this.ref.point = ec.curve .point(point.x, point.y, point.z, point.t) .add(p2.ref.point); return this; } /** @inheritdoc */ sub(p1, p2) { const point = p1.ref.point; this.ref.point = ec.curve .point(point.x, point.y, point.z, point.t) .add(p2.ref.point.neg()); return this; } /** @inheritdoc */ neg(p) { this.ref.point = p.ref.point.neg(); return this; } /** @inheritdoc */ mul(s, p) { p = p || null; const arr = s.ref.arr; this.ref.point = p !== null ? p.ref.point.mul(arr) : ec.curve.g.mul(arr); return this; } /** @inheritdoc */ marshalSize() { return 32; } /** @inheritdoc */ marshalBinary() { this.ref.point.normalize(); const buffer = this.ref.point.getY().toArray("le", 32); buffer[31] ^= (this.ref.point.x.isOdd() ? 1 : 0) << 7; return Buffer.from(buffer); } /** @inheritdoc */ unmarshalBinary(bytes) { // we create a copy because the array might be modified const buff = Buffer.from(bytes); const odd = buff[31] >> 7 === 1; buff[31] &= 0x7f; const bnp = new bn_js_1.default(buff, 16, "le"); if (bnp.cmp(ec.curve.p) >= 0) { throw new Error("bytes > p"); } this.ref.point = ec.curve.pointFromY(bnp, odd); } inspect() { return this.toString(); } /** @inheritdoc */ equals(p2) { const b1 = this.marshalBinary(); const b2 = p2.marshalBinary(); for (let i = 0; i < 32; i++) { if (b1[i] !== b2[i]) { return false; } } return true; } /** @inheritdoc */ toString() { const bytes = this.marshalBinary(); return Array.from(bytes, (b) => ("0" + (b & 0xff).toString(16)).slice(-2)).join(""); } /** @inheritdoc */ toProto() { return Buffer.concat([Ed25519Point.MARSHAL_ID, this.marshalBinary()]); } } Ed25519Point.MARSHAL_ID = Buffer.from("ed.point"); exports.default = Ed25519Point;