@vostokplatform/voting-encrypt
Advanced tools
Comparing version 0.1.13 to 0.11.1
@@ -9,4 +9,2 @@ import { Config, EncryptedBulletin, KeyPair, Point } from './interfaces'; | ||
private readonly pedersenBase; | ||
private readonly compressed; | ||
private readonly packed; | ||
constructor(cryptoParams: Config); | ||
@@ -19,7 +17,6 @@ private createPoint; | ||
private asPoint; | ||
static pack: (data: any) => any; | ||
static unpack: (data: any) => any; | ||
private calculateRangeProof; | ||
private proveEqualityOfDLEx; | ||
makeEncryptedBulletin(bulletin: number[]): EncryptedBulletin; | ||
calculateMainKey(keyPairs: KeyPair[]): Point; | ||
} |
@@ -1,2 +0,2 @@ | ||
!function(e,t){if("object"==typeof exports&&"object"==typeof module)module.exports=t(require("elliptic"),require("bn.js"),require("base85"));else if("function"==typeof define&&define.amd)define(["elliptic","bn.js","base85"],t);else{var n="object"==typeof exports?t(require("elliptic"),require("bn.js"),require("base85")):t(e.elliptic,e["bn.js"],e.base85);for(var r in n)("object"==typeof exports?exports:e)[r]=n[r]}}(this,(function(e,t,n){return function(e){var t={};function n(r){if(t[r])return t[r].exports;var i=t[r]={i:r,l:!1,exports:{}};return e[r].call(i.exports,i,i.exports,n),i.l=!0,i.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var i in e)n.d(r,i,function(t){return e[t]}.bind(null,i));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=0)}([function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});const r=n(1),i=n(2),a=n(3),s=n(4);class o{constructor(e){this.cryptoParams=e,this.ec=new r.ec("secp256k1");const{mainKey:t,basePoint:n,pedersenBase:i}=this.cryptoParams;this.base=this.createPoint(n),this.mainKey=this.createPoint(t),this.pointAtInfinity=this.base.add(this.base.neg()),this.pedersenBase=this.createPoint(i),this.compressed=e.compressed||!1,this.packed=e.packed||!1}createPoint(e){const t=new a(e[0]).toString(16).padStart(64,"0"),n=new a(e[1]).toString(16).padStart(64,"0");return this.ec.keyFromPublic(`04${t}${n}`,"hex").getPublic()}generatePrivateKey(){return new a(this.ec.genKeyPair().getPrivate().toString())}generateRandomFromScalarField(){return this.generatePrivateKey()}generateRandomLessThan(e){let t=new a(2).pow(new a(521)),n=this.generateRandomFromScalarField().umod(e);for(;e>t;)n.imul(this.generateRandomFromScalarField()),t.imul(t);return n.umod(e)}hashPoints(e){const t=i.createHash("sha256");return e.map(e=>{const[n,r]=this.asPoint(e);t.update(`${n},${r},`)}),new a(t.digest("hex"),16)}asPoint(e){return this.compressed?new a(e.encode("hex",!0),16).toString():e.isInfinity()?["0","1"]:[e.getX().toString(),e.getY().toString()]}calculateRangeProof(e,t,n,r,i){const{q:s,hashLength:o}=this.cryptoParams,c=new a(2).pow(new a(o));let u=[],d=[];if(0===e){const e=this.generateRandomLessThan(c),o=this.generateRandomFromScalarField(),l=n.add(this.base.neg()),m=this.base.mul(o).add(t.mul(e).neg()),p=i.mul(o).add(l.mul(e).neg()),h=this.generateRandomFromScalarField(),f=this.base.mul(h),g=i.mul(h),y=this.hashPoints([i,t,n,f,g,m,p]).add(e.neg()).umod(c),b=h.add(y.mul(r)).umod(new a(s));u=[t,n,f,m,g,p].map(this.asPoint.bind(this)),d=[y,e,b,o]}else if(1===e){const e=this.generateRandomLessThan(c),o=this.generateRandomFromScalarField(),l=n,m=this.base.mul(o).add(t.mul(e).neg()),p=i.mul(o).add(l.mul(e).neg()),h=this.generateRandomFromScalarField(),f=this.base.mul(h),g=i.mul(h),y=this.hashPoints([i,t,n,m,p,f,g]).add(e.neg()).umod(c),b=h.add(y.mul(r)).umod(new a(s));u=[t,n,m,f,p,g].map(this.asPoint.bind(this)),d=[e,y,o,b]}else u=Array(6).fill(this.pointAtInfinity),d=["0","0","0","0"];return[...u,...d.map(String)]}makeEncryptedBulletin(e){const{q:t}=this.cryptoParams;let n=0,r=this.pointAtInfinity,i=this.pointAtInfinity,s=new a(0);const c=[e.map(e=>{n+=e;const o=this.base.mul(new a(e)),c=this.generateRandomFromScalarField(),u=this.base.mul(c),d=this.mainKey.mul(c).add(o);return r=r.add(u),i=i.add(d),s=s.add(c).umod(new a(t)),this.calculateRangeProof(e,u,d,c,this.mainKey)}),this.calculateRangeProof(n,r,i,s,this.mainKey).slice(2)];return this.packed?o.pack(c):c}calculateMainKey(e){const t=e.reduce((e,t)=>{const n=this.createPoint(t.publicKey).add(this.pedersenBase.neg().mul(new a(t.privateKey)));return e.add(n)},this.pointAtInfinity);return[t.getX().toString(),t.getY().toString()]}}t.Encrypt=o,o.pack=e=>Array.isArray(e)?e.map(o.pack):s.encode(new a(e).toBuffer(),"ascii85"),o.unpack=e=>Array.isArray(e)?e.map(o.unpack):new a(s.decode(e)).toString(10)},function(t,n){t.exports=e},function(e,t){e.exports=require("crypto")},function(e,n){e.exports=t},function(e,t){e.exports=n}])})); | ||
!function(e,t){if("object"==typeof exports&&"object"==typeof module)module.exports=t(require("elliptic"),require("bn.js"));else if("function"==typeof define&&define.amd)define(["elliptic","bn.js"],t);else{var n="object"==typeof exports?t(require("elliptic"),require("bn.js")):t(e.elliptic,e["bn.js"]);for(var r in n)("object"==typeof exports?exports:e)[r]=n[r]}}(this,(function(e,t){return function(e){var t={};function n(r){if(t[r])return t[r].exports;var i=t[r]={i:r,l:!1,exports:{}};return e[r].call(i.exports,i,i.exports,n),i.l=!0,i.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var i in e)n.d(r,i,function(t){return e[t]}.bind(null,i));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=0)}([function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});const r=n(1),i=n(2),a=n(3);t.Encrypt=class{constructor(e){this.cryptoParams=e,this.ec=new r.ec("secp256k1");const{mainKey:t,basePoint:n,pedersenBase:i}=this.cryptoParams;this.base=this.createPoint(n),this.mainKey=this.createPoint(t),this.pointAtInfinity=this.base.add(this.base.neg()),this.pedersenBase=this.createPoint(i)}createPoint(e){const t=new a(e[0]).toString(16).padStart(64,"0"),n=new a(e[1]).toString(16).padStart(64,"0");return this.ec.keyFromPublic(`04${t}${n}`,"hex").getPublic()}generatePrivateKey(){return new a(this.ec.genKeyPair().getPrivate().toString())}generateRandomFromScalarField(){return this.generatePrivateKey()}generateRandomLessThan(e){let t=new a(2).pow(new a(521)),n=this.generateRandomFromScalarField().umod(e);for(;e>t;)n.imul(this.generateRandomFromScalarField()),t.imul(t);return n.umod(e)}hashPoints(e){const t=i.createHash("sha256");return e.map(e=>{const[n,r]=this.asPoint(e);t.update(`${n},${r},`)}),new a(t.digest("hex"),16)}asPoint(e){if(e.isInfinity())throw new Error("Calculation error");return[e.getX().toString(),e.getY().toString()]}calculateRangeProof(e,t,n,r,i){const{q:o,hashLength:s}=this.cryptoParams,u=new a(2).pow(new a(s));let l=[],d=[];if(0===e){const e=this.generateRandomLessThan(u),s=this.generateRandomFromScalarField(),c=n.add(this.base.neg()),h=this.base.mul(s).add(t.mul(e).neg()),m=i.mul(s).add(c.mul(e).neg()),p=this.generateRandomFromScalarField(),f=this.base.mul(p),g=i.mul(p),y=this.hashPoints([i,t,n,f,g,h,m]).add(e.neg()).umod(u),b=p.add(y.mul(r)).umod(new a(o));l=[t,n,f,h,g,m].map(this.asPoint.bind(this)),d=[y,e,b,s]}else if(1===e){const e=this.generateRandomLessThan(u),s=this.generateRandomFromScalarField(),c=n,h=this.base.mul(s).add(t.mul(e).neg()),m=i.mul(s).add(c.mul(e).neg()),p=this.generateRandomFromScalarField(),f=this.base.mul(p),g=i.mul(p),y=this.hashPoints([i,t,n,h,m,f,g]).add(e.neg()).umod(u),b=p.add(y.mul(r)).umod(new a(o));l=[t,n,h,f,m,g].map(this.asPoint.bind(this)),d=[e,y,s,b]}else l=Array(6).fill(this.pointAtInfinity),d=["0","0","0","0"];return[...l,...d.map(String)]}proveEqualityOfDLEx(e,t,n,r){const{q:i}=this.cryptoParams,o=this.base,s=this.mainKey,u=this.generateRandomFromScalarField(),l=o.mul(u),d=s.mul(u),c=this.hashPoints([l,d,o,t,s,n,...r]);return[e.mul(c).add(u).umod(new a(i)).toString(),this.asPoint(l),this.asPoint(d)]}makeEncryptedBulletin(e){if(1!==e.reduce((e,t)=>e+t,0))throw new Error("Bad bulletin");const{q:t}=this.cryptoParams;let n=this.pointAtInfinity,r=this.pointAtInfinity,i=new a(0);const o=[];return[e.map(e=>{const s=this.base.mul(new a(e)),u=this.generateRandomFromScalarField(),l=this.base.mul(u),d=this.mainKey.mul(u).add(s);return n=n.add(l),r=r.add(d),i=i.add(u).umod(new a(t)),o.push(l),this.calculateRangeProof(e,l,d,u,this.mainKey)}),this.proveEqualityOfDLEx(i,n,r.add(this.base.neg()),o)]}calculateMainKey(e){const t=e.reduce((e,t)=>{const n=this.createPoint(t.publicKey).add(this.pedersenBase.neg().mul(new a(t.privateKey)));return e.add(n)},this.pointAtInfinity);return[t.getX().toString(),t.getY().toString()]}}},function(t,n){t.exports=e},function(e,t){e.exports=require("crypto")},function(e,n){e.exports=t}])})); | ||
//# sourceMappingURL=index.js.map |
@@ -16,3 +16,3 @@ export declare type Point = [string, string] | string; | ||
export declare type RangeProof = [Point, Point, Point, Point, Point, Point, string, string, string, string]; | ||
export declare type RangeProofWithoutAB = [Point, Point, Point, Point, string, string, string, string]; | ||
export declare type EncryptedBulletin = [RangeProof[], RangeProofWithoutAB]; | ||
export declare type EqualityOfDLExProof = [string, Point, Point]; | ||
export declare type EncryptedBulletin = [RangeProof[], EqualityOfDLExProof]; |
{ | ||
"name": "@vostokplatform/voting-encrypt", | ||
"version": "0.1.13", | ||
"version": "0.11.1", | ||
"description": "", | ||
@@ -22,3 +22,2 @@ "main": "dist/index.js", | ||
"dependencies": { | ||
"base85": "^2.2.0", | ||
"bn.js": "^5.1.1", | ||
@@ -25,0 +24,0 @@ "elliptic": "^6.5.2" |
# Usage example | ||
### Init and ecrypt one question | ||
### Init and encrypt one question | ||
```js | ||
const { Encrypt } = requiere('@vostokplatform/voting-encrypt') | ||
const { Encrypt } = require('@vostokplatform/voting-encrypt') | ||
@@ -33,4 +33,2 @@ const basePoint = [ | ||
q, | ||
packed: false, // optional, use this to encode result in base85 | ||
compressed: false // optional, use this to compress points | ||
}) | ||
@@ -37,0 +35,0 @@ |
@@ -1,7 +0,5 @@ | ||
import { Config, EncryptedBulletin, KeyPair, Point, RangeProof, RangeProofWithoutAB } from './interfaces' | ||
import { Config, EncryptedBulletin, EqualityOfDLExProof, KeyPair, Point, RangeProof } from './interfaces' | ||
import * as elliptic from 'elliptic' | ||
import { createHash } from 'crypto' | ||
import * as BN from 'bn.js' | ||
// @ts-ignore | ||
import * as base85 from 'base85' | ||
@@ -16,7 +14,5 @@ type BasePoint = elliptic.curve.base.BasePoint | ||
private readonly pedersenBase: BasePoint | ||
private readonly compressed: boolean | ||
private readonly packed: boolean | ||
constructor ( | ||
private readonly cryptoParams: Config | ||
constructor( | ||
private readonly cryptoParams: Config, | ||
) { | ||
@@ -29,7 +25,5 @@ this.ec = new elliptic.ec('secp256k1') | ||
this.pedersenBase = this.createPoint(pedersenBase) | ||
this.compressed = cryptoParams.compressed || false | ||
this.packed = cryptoParams.packed || false | ||
} | ||
private createPoint (point: Point): BasePoint { | ||
private createPoint(point: Point): BasePoint { | ||
const x_hex = new BN(point[0]).toString(16).padStart(64, '0') | ||
@@ -40,11 +34,11 @@ const y_hex = new BN(point[1]).toString(16).padStart(64, '0') | ||
private generatePrivateKey (): BN { | ||
private generatePrivateKey(): BN { | ||
return new BN(this.ec.genKeyPair().getPrivate().toString()) | ||
} | ||
private generateRandomFromScalarField (): BN { | ||
private generateRandomFromScalarField(): BN { | ||
return this.generatePrivateKey() | ||
} | ||
private generateRandomLessThan (n: BN): BN { | ||
private generateRandomLessThan(n: BN): BN { | ||
let currentMaxNumber = new BN(2).pow(new BN(521)) | ||
@@ -61,3 +55,3 @@ let randomNumber = this.generateRandomFromScalarField().umod(n) | ||
private hashPoints (points: BasePoint[]): BN { | ||
private hashPoints(points: BasePoint[]): BN { | ||
const hash = createHash('sha256') | ||
@@ -73,18 +67,11 @@ | ||
private asPoint (point: BasePoint): Point | any { | ||
if (this.compressed) { | ||
return new BN(point.encode('hex', true), 16).toString() | ||
} else { | ||
return point.isInfinity() | ||
? ['0', '1'] | ||
: [point.getX().toString(), point.getY().toString()] | ||
private asPoint(point: BasePoint): Point | any { | ||
if (point.isInfinity()) { | ||
throw new Error('Calculation error') | ||
} | ||
return [point.getX().toString(), point.getY().toString()] | ||
} | ||
static pack = (data: any): any => Array.isArray(data) ? data.map(Encrypt.pack) : base85.encode(new BN(data).toBuffer(), 'ascii85') | ||
static unpack = (data: any): any => Array.isArray(data) ? data.map(Encrypt.unpack) : new BN(base85.decode(data)).toString(10) | ||
private calculateRangeProof(vote: number, A: BasePoint, B: BasePoint, r: BN, publicKey: BasePoint): RangeProof { | ||
private calculateRangeProof (vote: number, A: BasePoint, B: BasePoint, r: BN, publicKey: BasePoint): RangeProof { | ||
const { q, hashLength } = this.cryptoParams | ||
@@ -148,11 +135,31 @@ | ||
public makeEncryptedBulletin (bulletin: number[]): EncryptedBulletin { | ||
private proveEqualityOfDLEx( | ||
x: BN, | ||
Y1: BasePoint, | ||
Y2: BasePoint, | ||
listOfRs: BasePoint[], | ||
): EqualityOfDLExProof { | ||
const { q } = this.cryptoParams | ||
let sumVote = 0 | ||
const G1 = this.base | ||
const G2 = this.mainKey | ||
const u = this.generateRandomFromScalarField() | ||
const U1 = G1.mul(u) | ||
const U2 = G2.mul(u) | ||
const v = this.hashPoints([U1, U2, G1, Y1, G2, Y2, ...listOfRs]) | ||
const w = x.mul(v).add(u).umod(new BN(q)) | ||
return [w.toString(), this.asPoint(U1), this.asPoint(U2)] | ||
} | ||
public makeEncryptedBulletin(bulletin: number[]): EncryptedBulletin { | ||
if (bulletin.reduce((a, b) => a + b, 0) !== 1) { | ||
throw new Error('Bad bulletin') | ||
} | ||
const { q } = this.cryptoParams | ||
let sumR = this.pointAtInfinity | ||
let sumC = this.pointAtInfinity | ||
let sumr = new BN(0) | ||
const listOfRs: BasePoint[] = [] | ||
const encryptedBulletin = bulletin.map((vote) => { | ||
sumVote += vote | ||
const message = this.base.mul(new BN(vote)) | ||
@@ -166,13 +173,16 @@ const r = this.generateRandomFromScalarField() | ||
sumr = sumr.add(r).umod(new BN(q)) | ||
listOfRs.push(R) | ||
return this.calculateRangeProof(vote, R, C, r, this.mainKey) | ||
}) | ||
const sumRangeProof_withoutAB: RangeProofWithoutAB = this.calculateRangeProof(sumVote, sumR, sumC, sumr, this.mainKey).slice(2) as RangeProofWithoutAB | ||
const encrypted = [encryptedBulletin, sumRangeProof_withoutAB] | ||
return this.packed ? Encrypt.pack(encrypted) : encrypted | ||
const sumRangeProof = this.proveEqualityOfDLEx( | ||
sumr, | ||
sumR, | ||
sumC.add(this.base.neg()), | ||
listOfRs, | ||
) | ||
return [encryptedBulletin, sumRangeProof] | ||
} | ||
public calculateMainKey (keyPairs: KeyPair[]): Point { | ||
public calculateMainKey(keyPairs: KeyPair[]): Point { | ||
const mainKey = keyPairs.reduce((acc, keyPair) => { | ||
@@ -179,0 +189,0 @@ const point = this.createPoint(keyPair.publicKey) |
@@ -28,14 +28,9 @@ export type Point = [string, string] | string | ||
export type RangeProofWithoutAB = [ | ||
export type EqualityOfDLExProof = [ | ||
string, | ||
Point, | ||
Point, | ||
Point, | ||
Point, | ||
string, | ||
string, | ||
string, | ||
string, | ||
Point | ||
] | ||
export type EncryptedBulletin = [RangeProof[], RangeProofWithoutAB] | ||
export type EncryptedBulletin = [RangeProof[], EqualityOfDLExProof] | ||
Sorry, the diff of this file is not supported yet
2
505
52725
82
- Removedbase85@^2.2.0
- Removedbase85@2.2.0(transitive)
- Removedbignum@0.13.1(transitive)
- Removedbindings@1.5.0(transitive)
- Removedfile-uri-to-path@1.0.0(transitive)
- Removedip-address@5.9.4(transitive)
- Removedjsbn@1.1.0(transitive)
- Removedlodash@4.17.21(transitive)
- Removednan@2.22.0(transitive)
- Removedsafe-buffer@5.2.1(transitive)
- Removedsprintf-js@1.1.2(transitive)
- Removedunderscore@1.13.7(transitive)