Skip to content

Commit 784e0a9

Browse files
committed
Test for Blind sig utils
Signed-off-by: lovesh <lovesh.bond@gmail.com>
1 parent 0237c43 commit 784e0a9

File tree

9 files changed

+482
-65
lines changed

9 files changed

+482
-65
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@docknetwork/crypto-wasm-ts",
3-
"version": "0.19.0",
3+
"version": "0.20.0",
44
"description": "Typescript abstractions over Dock's Rust crypto library's WASM wrapper",
55
"homepage": "https://github.com/docknetwork/crypto-wasm-ts",
66
"main": "lib/crypto-wasm-ts/src/index.js",

src/accumulator/accumulator.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ import {
3131
universalAccumulatorVerifyNonMembership
3232
} from '@docknetwork/crypto-wasm';
3333
import { MembershipWitness, NonMembershipWitness } from './accumulatorWitness';
34-
import { ensurePositiveIntegerOfSize, getUint8ArraysFromObject } from '../util';
34+
import { getUint8ArraysFromObject } from '../util';
3535
import { IAccumulatorState, IUniversalAccumulatorState } from './IAccumulatorState';
3636
import { IInitialElementsStore } from './IInitialElementsStore';
3737
import {

src/accumulator/in-memory-persistence.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { IInitialElementsStore } from './IInitialElementsStore';
55
* In memory implementation of the state. For testing only
66
*/
77
export class InMemoryState implements IAccumulatorState {
8+
// Converts item to string (JSON.stringify) before adding to set as equality checks wont work with Uint8Array.
89
state: Set<string>;
910
constructor() {
1011
this.state = new Set<string>();
@@ -50,6 +51,7 @@ export class InMemoryUniversalState extends InMemoryState implements IUniversalA
5051
}
5152

5253
export class InMemoryInitialElementsStore implements IInitialElementsStore {
54+
// Converts item to string (JSON.stringify) before adding to set as equality checks wont work with Uint8Array.
5355
store: Set<string>;
5456
constructor() {
5557
this.store = new Set<string>();

src/bbs-plus/encoder.ts

Lines changed: 76 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@ import { flattenObjectToKeyValuesList, isPositiveInteger } from '../util';
66
*/
77
export type EncodeFunc = (value: unknown) => Uint8Array;
88

9+
/**
10+
* A function that encodes the input to a positive integer
11+
*/
12+
export type ToPositiveIntFunc = (value: unknown) => number;
13+
914
/**
1015
* Encodes the input to a field element for signing with BBS+ in group G1.
1116
* Used when working with messages that are specified as JS objects. This encoder object will contain
@@ -29,13 +34,14 @@ export class Encoder {
2934
* Encode a message with given name and value. Will throw an error if no appropriate encoder found.
3035
* @param name
3136
* @param value
37+
* @param strict - If set to false and no appropriate encoder is found but the value is a bytearray, it will encode it using the built-in mechanism
3238
*/
33-
encodeMessage(name: string, value: unknown): Uint8Array {
39+
encodeMessage(name: string, value: unknown, strict = false): Uint8Array {
3440
const encoder = this.encoders?.get(name) || this.defaultEncoder;
3541
if (encoder !== undefined) {
3642
return encoder(value);
3743
} else {
38-
if (value instanceof Uint8Array) {
44+
if (!strict && value instanceof Uint8Array) {
3945
return SignatureG1.encodeMessageForSigning(value);
4046
} else {
4147
throw new Error(
@@ -49,12 +55,13 @@ export class Encoder {
4955
* Encode messages given as JS object. It flattens the object into a sorted list and encodes each value as per the known
5056
* encoding functions Returns 2 arrays, 1st with message names and 2nd with encoded values.
5157
* @param messages
58+
* @param strict - If set to false and no appropriate encoder is found but the value is a bytearray, it will encode it using the built-in mechanism
5259
*/
53-
encodeMessageObject(messages: object): [string[], Uint8Array[]] {
60+
encodeMessageObject(messages: object, strict = false): [string[], Uint8Array[]] {
5461
const [names, values] = flattenObjectToKeyValuesList(messages);
5562
const encoded: Uint8Array[] = [];
5663
for (let i = 0; i < names.length; i++) {
57-
encoded.push(this.encodeMessage(names[i], values[i]));
64+
encoded.push(this.encodeMessage(names[i], values[i], strict));
5865
}
5966
return [names, encoded];
6067
}
@@ -67,27 +74,58 @@ export class Encoder {
6774
if (!isPositiveInteger(v)) {
6875
throw new Error(`Expected positive integer but ${v} has type ${typeof v}`);
6976
}
70-
// @ts-ignore
71-
return SignatureG1.encodePositiveNumberForSigning(v);
77+
return SignatureG1.encodePositiveNumberForSigning(v as number);
7278
};
7379
}
7480

7581
/**
76-
* Returns an encoding function to be used on a message that can be a positive or negative integer.
77-
* @param minimum - The minimum negative value that the message can take
82+
* Returns a function that can convert any input integer to a positive integer when its minimum
83+
* negative value is known. Does that by adding an offset of abs(minimum) to the input
84+
* @param minimum
7885
*/
79-
static integerEncoder(minimum: number): EncodeFunc {
86+
static integerToPositiveInt(minimum: number): ToPositiveIntFunc {
87+
if (!Number.isInteger(minimum)) {
88+
throw new Error(`Expected integer but ${minimum} has type ${typeof minimum}`);
89+
}
8090
const offset = Math.abs(minimum);
8191
return (v: unknown) => {
8292
if (!Number.isInteger(v)) {
8393
throw new Error(`Expected integer but ${v} has type ${typeof v}`);
8494
}
85-
// @ts-ignore
86-
if (v < minimum) {
87-
throw new Error(`Encoder was created with minimum value ${minimum} but was asked to encode ${v}`);
95+
const vNum = v as number;
96+
if (vNum < minimum) {
97+
throw new Error(`Encoder was created with minimum value ${minimum} but was asked to encode ${vNum}`);
8898
}
89-
// @ts-ignore
90-
return SignatureG1.encodePositiveNumberForSigning(offset + v);
99+
return offset + vNum;
100+
};
101+
}
102+
103+
/**
104+
* Returns an encoding function to be used on a message that can be a positive or negative integer.
105+
* @param minimum - The minimum negative value that the message can take
106+
*/
107+
static integerEncoder(minimum: number): EncodeFunc {
108+
const f = Encoder.integerToPositiveInt(minimum);
109+
return (v: unknown) => {
110+
return SignatureG1.encodePositiveNumberForSigning(f(v));
111+
};
112+
}
113+
114+
/**
115+
* Returns a function that can convert any positive number to a positive integer when its maximum decimal
116+
* places are known. Does that by multiplying it by 10^max_decimal_places, eg. 23.452 -> 23452
117+
* @param maxDecimalPlaces
118+
*/
119+
static positiveDecimalNumberToPositiveInt(maxDecimalPlaces: number): ToPositiveIntFunc {
120+
if (!isPositiveInteger(maxDecimalPlaces)) {
121+
throw new Error(`Maximum decimal places should be a positive integer but was ${maxDecimalPlaces}`);
122+
}
123+
const multiple = Math.pow(10, maxDecimalPlaces);
124+
return (v: unknown) => {
125+
Encoder.ensureNumber(v);
126+
const vNum = v as number;
127+
Encoder.ensureCorrectDecimalNumberPlaces(vNum, maxDecimalPlaces);
128+
return Math.trunc(vNum * multiple);
91129
};
92130
}
93131

@@ -96,16 +134,32 @@ export class Encoder {
96134
* @param maxDecimalPlaces - The maximum decimal places
97135
*/
98136
static positiveDecimalNumberEncoder(maxDecimalPlaces: number): EncodeFunc {
99-
if (!Number.isInteger(maxDecimalPlaces) || maxDecimalPlaces < 1) {
100-
throw new Error(`Maximum decimal places should be a positive integer greater than 1 but was ${maxDecimalPlaces}`);
137+
const f = Encoder.positiveDecimalNumberToPositiveInt(maxDecimalPlaces);
138+
return (v: unknown) => {
139+
return SignatureG1.encodePositiveNumberForSigning(f(v));
140+
};
141+
}
142+
143+
/**
144+
* Returns a function that can convert any number to a positive integer when its minimum negative value and maximum
145+
* decimal places are known. Does that by adding an offset of abs(minimum) and then multiplying it by 10^max_decimal_places
146+
* @param minimum
147+
* @param maxDecimalPlaces
148+
*/
149+
static decimalNumberToPositiveInt(minimum: number, maxDecimalPlaces: number): ToPositiveIntFunc {
150+
if (!isPositiveInteger(maxDecimalPlaces)) {
151+
throw new Error(`Maximum decimal places should be a positive integer but was ${maxDecimalPlaces}`);
101152
}
153+
const offset = Math.abs(minimum);
102154
const multiple = Math.pow(10, maxDecimalPlaces);
103155
return (v: unknown) => {
104156
Encoder.ensureNumber(v);
105-
// @ts-ignore
106-
Encoder.ensureCorrectDecimalNumberPlaces(v, maxDecimalPlaces);
107-
// @ts-ignore
108-
return SignatureG1.encodePositiveNumberForSigning(Math.trunc(v * multiple));
157+
const vNum = v as number;
158+
if (vNum < minimum) {
159+
throw new Error(`Encoder was created with minimum value ${minimum} but was asked to encode ${vNum}`);
160+
}
161+
Encoder.ensureCorrectDecimalNumberPlaces(vNum, maxDecimalPlaces);
162+
return Math.trunc((offset + vNum) * multiple);
109163
};
110164
}
111165

@@ -115,21 +169,9 @@ export class Encoder {
115169
* @param maxDecimalPlaces - The maximum decimal places
116170
*/
117171
static decimalNumberEncoder(minimum: number, maxDecimalPlaces: number): EncodeFunc {
118-
if (!Number.isInteger(maxDecimalPlaces) || maxDecimalPlaces < 1) {
119-
throw new Error(`Maximum decimal places should be a positive integer greater than 1 but was ${maxDecimalPlaces}`);
120-
}
121-
const offset = Math.abs(minimum);
122-
const multiple = Math.pow(10, maxDecimalPlaces);
172+
const f = Encoder.decimalNumberToPositiveInt(minimum, maxDecimalPlaces);
123173
return (v: unknown) => {
124-
Encoder.ensureNumber(v);
125-
// @ts-ignore
126-
if (v < minimum) {
127-
throw new Error(`Encoder was created with minimum value ${minimum} but was asked to encode ${v}`);
128-
}
129-
// @ts-ignore
130-
Encoder.ensureCorrectDecimalNumberPlaces(v, maxDecimalPlaces);
131-
// @ts-ignore
132-
return SignatureG1.encodePositiveNumberForSigning(Math.trunc((offset + v) * multiple));
174+
return SignatureG1.encodePositiveNumberForSigning(f(v));
133175
};
134176
}
135177

src/bbs-plus/signature.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ export class BlindSignatureG1 extends BlindSignature {
207207
/**
208208
* Structure to send to the signer to request a blind signature
209209
*/
210-
interface BlindSignatureRequest {
210+
export interface BlindSignatureRequest {
211211
/**
212212
* The commitment to the blinded messages
213213
*/

src/bytearray-wrapper.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { bytearrayToHex } from './util';
2+
13
/**
24
* Wraps a bytearray, i.e. Uint8Array. Used to give distinct types to objects as most of them are bytearrays because that
35
* is what the WASM bindings accept and return.
@@ -22,4 +24,11 @@ export class BytearrayWrapper {
2224
get length(): number {
2325
return this.value.length;
2426
}
27+
28+
/**
29+
* Return the hex representation of the wrapped bytearray
30+
*/
31+
get hex(): string {
32+
return bytearrayToHex(this.value);
33+
}
2534
}

0 commit comments

Comments
 (0)