@iam-protocol/pulse-sdk 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +16 -2
- package/dist/index.d.ts +16 -2
- package/dist/index.js +67 -7
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +64 -7
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/config.ts +2 -1
- package/src/extraction/kinematic.ts +28 -5
- package/src/extraction/mfcc.ts +11 -4
- package/src/extraction/statistics.ts +46 -0
- package/src/index.ts +2 -2
- package/src/proof/prover.ts +4 -2
- package/src/proof/types.ts +1 -0
- package/src/pulse.ts +1 -1
- package/test/integration.test.ts +3 -2
- package/test/serializer.test.ts +1 -0
package/dist/index.mjs
CHANGED
|
@@ -12946,6 +12946,7 @@ var BN254_SCALAR_FIELD = BigInt(
|
|
|
12946
12946
|
);
|
|
12947
12947
|
var FINGERPRINT_BITS = 256;
|
|
12948
12948
|
var DEFAULT_THRESHOLD = 30;
|
|
12949
|
+
var DEFAULT_MIN_DISTANCE = 3;
|
|
12949
12950
|
var PROOF_A_SIZE = 64;
|
|
12950
12951
|
var PROOF_B_SIZE = 128;
|
|
12951
12952
|
var PROOF_C_SIZE = 64;
|
|
@@ -13185,6 +13186,37 @@ function condense(values) {
|
|
|
13185
13186
|
kurtosis: kurtosis(values)
|
|
13186
13187
|
};
|
|
13187
13188
|
}
|
|
13189
|
+
function entropy(values, bins = 16) {
|
|
13190
|
+
if (values.length < 2) return 0;
|
|
13191
|
+
const min = Math.min(...values);
|
|
13192
|
+
const max = Math.max(...values);
|
|
13193
|
+
if (min === max) return 0;
|
|
13194
|
+
const counts = new Array(bins).fill(0);
|
|
13195
|
+
const range = max - min;
|
|
13196
|
+
for (const v of values) {
|
|
13197
|
+
const idx = Math.min(Math.floor((v - min) / range * bins), bins - 1);
|
|
13198
|
+
counts[idx]++;
|
|
13199
|
+
}
|
|
13200
|
+
let h = 0;
|
|
13201
|
+
for (const c of counts) {
|
|
13202
|
+
if (c > 0) {
|
|
13203
|
+
const p = c / values.length;
|
|
13204
|
+
h -= p * Math.log2(p);
|
|
13205
|
+
}
|
|
13206
|
+
}
|
|
13207
|
+
return h;
|
|
13208
|
+
}
|
|
13209
|
+
function autocorrelation(values, lag = 1) {
|
|
13210
|
+
if (values.length <= lag) return 0;
|
|
13211
|
+
const m = mean(values);
|
|
13212
|
+
const v = variance(values, m);
|
|
13213
|
+
if (v === 0) return 0;
|
|
13214
|
+
let sum = 0;
|
|
13215
|
+
for (let i = 0; i < values.length - lag; i++) {
|
|
13216
|
+
sum += (values[i] - m) * (values[i + lag] - m);
|
|
13217
|
+
}
|
|
13218
|
+
return sum / ((values.length - lag) * v);
|
|
13219
|
+
}
|
|
13188
13220
|
function fuseFeatures(audio, motion, touch) {
|
|
13189
13221
|
return [...audio, ...motion, ...touch];
|
|
13190
13222
|
}
|
|
@@ -13199,10 +13231,10 @@ function extractMFCC(audio) {
|
|
|
13199
13231
|
try {
|
|
13200
13232
|
Meyda = __require("meyda");
|
|
13201
13233
|
} catch {
|
|
13202
|
-
return new Array(NUM_MFCC * 3 * 4).fill(0);
|
|
13234
|
+
return new Array(NUM_MFCC * 3 * 4 + NUM_MFCC).fill(0);
|
|
13203
13235
|
}
|
|
13204
13236
|
const numFrames = Math.floor((samples.length - FRAME_SIZE) / HOP_SIZE) + 1;
|
|
13205
|
-
if (numFrames < 3) return new Array(NUM_MFCC * 3 * 4).fill(0);
|
|
13237
|
+
if (numFrames < 3) return new Array(NUM_MFCC * 3 * 4 + NUM_MFCC).fill(0);
|
|
13206
13238
|
const mfccFrames = [];
|
|
13207
13239
|
for (let i = 0; i < numFrames; i++) {
|
|
13208
13240
|
const start = i * HOP_SIZE;
|
|
@@ -13237,6 +13269,10 @@ function extractMFCC(audio) {
|
|
|
13237
13269
|
const stats = condense(dd);
|
|
13238
13270
|
features.push(stats.mean, stats.variance, stats.skewness, stats.kurtosis);
|
|
13239
13271
|
}
|
|
13272
|
+
for (let c = 0; c < NUM_MFCC; c++) {
|
|
13273
|
+
const raw = mfccFrames.map((f) => f[c] ?? 0);
|
|
13274
|
+
features.push(entropy(raw));
|
|
13275
|
+
}
|
|
13240
13276
|
return features;
|
|
13241
13277
|
}
|
|
13242
13278
|
function computeDeltas(frames) {
|
|
@@ -13251,7 +13287,7 @@ function computeDeltas(frames) {
|
|
|
13251
13287
|
|
|
13252
13288
|
// src/extraction/kinematic.ts
|
|
13253
13289
|
function extractMotionFeatures(samples) {
|
|
13254
|
-
if (samples.length < 5) return new Array(
|
|
13290
|
+
if (samples.length < 5) return new Array(54).fill(0);
|
|
13255
13291
|
const axes = {
|
|
13256
13292
|
ax: samples.map((s) => s.ax),
|
|
13257
13293
|
ay: samples.map((s) => s.ay),
|
|
@@ -13277,10 +13313,19 @@ function extractMotionFeatures(samples) {
|
|
|
13277
13313
|
jounceStats.kurtosis
|
|
13278
13314
|
);
|
|
13279
13315
|
}
|
|
13316
|
+
for (const values of Object.values(axes)) {
|
|
13317
|
+
const jerk = derivative(values);
|
|
13318
|
+
const windowSize = Math.max(5, Math.floor(jerk.length / 4));
|
|
13319
|
+
const windowVariances = [];
|
|
13320
|
+
for (let i = 0; i <= jerk.length - windowSize; i += windowSize) {
|
|
13321
|
+
windowVariances.push(variance(jerk.slice(i, i + windowSize)));
|
|
13322
|
+
}
|
|
13323
|
+
features.push(windowVariances.length >= 2 ? variance(windowVariances) : 0);
|
|
13324
|
+
}
|
|
13280
13325
|
return features;
|
|
13281
13326
|
}
|
|
13282
13327
|
function extractTouchFeatures(samples) {
|
|
13283
|
-
if (samples.length < 5) return new Array(
|
|
13328
|
+
if (samples.length < 5) return new Array(36).fill(0);
|
|
13284
13329
|
const x = samples.map((s) => s.x);
|
|
13285
13330
|
const y = samples.map((s) => s.y);
|
|
13286
13331
|
const pressure = samples.map((s) => s.pressure);
|
|
@@ -13300,6 +13345,14 @@ function extractTouchFeatures(samples) {
|
|
|
13300
13345
|
const jerkY = derivative(accY);
|
|
13301
13346
|
features.push(...Object.values(condense(jerkX)));
|
|
13302
13347
|
features.push(...Object.values(condense(jerkY)));
|
|
13348
|
+
for (const values of [vx, vy, pressure, area]) {
|
|
13349
|
+
const windowSize = Math.max(5, Math.floor(values.length / 4));
|
|
13350
|
+
const windowVariances = [];
|
|
13351
|
+
for (let i = 0; i <= values.length - windowSize; i += windowSize) {
|
|
13352
|
+
windowVariances.push(variance(values.slice(i, i + windowSize)));
|
|
13353
|
+
}
|
|
13354
|
+
features.push(windowVariances.length >= 2 ? variance(windowVariances) : 0);
|
|
13355
|
+
}
|
|
13303
13356
|
return features;
|
|
13304
13357
|
}
|
|
13305
13358
|
function derivative(values) {
|
|
@@ -13481,7 +13534,7 @@ async function getSnarkjs() {
|
|
|
13481
13534
|
}
|
|
13482
13535
|
return snarkjsModule;
|
|
13483
13536
|
}
|
|
13484
|
-
function prepareCircuitInput(current, previous, threshold = DEFAULT_THRESHOLD) {
|
|
13537
|
+
function prepareCircuitInput(current, previous, threshold = DEFAULT_THRESHOLD, minDistance = DEFAULT_MIN_DISTANCE) {
|
|
13485
13538
|
return {
|
|
13486
13539
|
ft_new: current.fingerprint,
|
|
13487
13540
|
ft_prev: previous.fingerprint,
|
|
@@ -13489,7 +13542,8 @@ function prepareCircuitInput(current, previous, threshold = DEFAULT_THRESHOLD) {
|
|
|
13489
13542
|
salt_prev: previous.salt.toString(),
|
|
13490
13543
|
commitment_new: current.commitment.toString(),
|
|
13491
13544
|
commitment_prev: previous.commitment.toString(),
|
|
13492
|
-
threshold: threshold.toString()
|
|
13545
|
+
threshold: threshold.toString(),
|
|
13546
|
+
min_distance: minDistance.toString()
|
|
13493
13547
|
};
|
|
13494
13548
|
}
|
|
13495
13549
|
async function generateProof(input, wasmPath, zkeyPath) {
|
|
@@ -13707,7 +13761,7 @@ var inMemoryStore = null;
|
|
|
13707
13761
|
|
|
13708
13762
|
// src/pulse.ts
|
|
13709
13763
|
function extractFeatures(data) {
|
|
13710
|
-
const audioFeatures = data.audio ? extractMFCC(data.audio) : new Array(
|
|
13764
|
+
const audioFeatures = data.audio ? extractMFCC(data.audio) : new Array(169).fill(0);
|
|
13711
13765
|
const motionFeatures = extractMotionFeatures(data.motion);
|
|
13712
13766
|
const touchFeatures = extractTouchFeatures(data.touch);
|
|
13713
13767
|
return fuseFeatures(audioFeatures, motionFeatures, touchFeatures);
|
|
@@ -14089,6 +14143,7 @@ function generateLissajousPoints(params) {
|
|
|
14089
14143
|
}
|
|
14090
14144
|
export {
|
|
14091
14145
|
DEFAULT_CAPTURE_MS,
|
|
14146
|
+
DEFAULT_MIN_DISTANCE,
|
|
14092
14147
|
DEFAULT_THRESHOLD,
|
|
14093
14148
|
FINGERPRINT_BITS,
|
|
14094
14149
|
MAX_CAPTURE_MS,
|
|
@@ -14096,9 +14151,11 @@ export {
|
|
|
14096
14151
|
PROGRAM_IDS,
|
|
14097
14152
|
PulseSDK,
|
|
14098
14153
|
PulseSession,
|
|
14154
|
+
autocorrelation,
|
|
14099
14155
|
bigintToBytes32,
|
|
14100
14156
|
computeCommitment,
|
|
14101
14157
|
condense,
|
|
14158
|
+
entropy,
|
|
14102
14159
|
fetchIdentityState,
|
|
14103
14160
|
fuseFeatures,
|
|
14104
14161
|
generateLissajousPoints,
|