@aztec/foundation 0.27.1 → 0.27.2

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.
@@ -41,5 +41,10 @@ export declare class EventSelector extends Selector {
41
41
  * @returns An empty selector.
42
42
  */
43
43
  static empty(): EventSelector;
44
+ /**
45
+ * Creates a random selector.
46
+ * @returns A random selector.
47
+ */
48
+ static random(): EventSelector;
44
49
  }
45
50
  //# sourceMappingURL=event_selector.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"event_selector.d.ts","sourceRoot":"","sources":["../../src/abi/event_selector.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,EAAE,EAAE,MAAM,qBAAqB,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAC7D,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAIzC,8BAA8B;AAC9B,MAAM,WAAW,aAAa;IAC5B,aAAa;IACb,SAAS,EAAE,eAAe,CAAC;CAC5B;AAED,gFAAgF;AAChF,qBAAa,aAAc,SAAQ,QAAQ;IACzC;;;;OAIG;IACH,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,YAAY;IAM/C;;;;OAIG;IACH,MAAM,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE;IAIvB;;;;OAIG;IACH,MAAM,CAAC,aAAa,CAAC,SAAS,EAAE,MAAM;IAQtC;;;;;;;OAOG;IACH,MAAM,CAAC,UAAU,CAAC,QAAQ,EAAE,MAAM;IAQlC;;;OAGG;IACH,MAAM,CAAC,KAAK;CAGb"}
1
+ {"version":3,"file":"event_selector.d.ts","sourceRoot":"","sources":["../../src/abi/event_selector.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,EAAE,EAAE,MAAM,qBAAqB,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAC7D,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAIzC,8BAA8B;AAC9B,MAAM,WAAW,aAAa;IAC5B,aAAa;IACb,SAAS,EAAE,eAAe,CAAC;CAC5B;AAED,gFAAgF;AAChF,qBAAa,aAAc,SAAQ,QAAQ;IACzC;;;;OAIG;IACH,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,YAAY;IAM/C;;;;OAIG;IACH,MAAM,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE;IAIvB;;;;OAIG;IACH,MAAM,CAAC,aAAa,CAAC,SAAS,EAAE,MAAM;IAQtC;;;;;;;OAOG;IACH,MAAM,CAAC,UAAU,CAAC,QAAQ,EAAE,MAAM;IAQlC;;;OAGG;IACH,MAAM,CAAC,KAAK;IAIZ;;;OAGG;IACH,MAAM,CAAC,MAAM;CAGd"}
@@ -1,5 +1,5 @@
1
1
  import { fromHex, toBigIntBE } from '../bigint-buffer/index.js';
2
- import { keccak } from '../crypto/index.js';
2
+ import { keccak, randomBytes } from '../crypto/index.js';
3
3
  import { BufferReader } from '../serialize/buffer_reader.js';
4
4
  import { Selector } from './selector.js';
5
5
  /** An event selector is the first 4 bytes of the hash of an event signature. */
@@ -56,5 +56,12 @@ export class EventSelector extends Selector {
56
56
  static empty() {
57
57
  return new EventSelector(0);
58
58
  }
59
+ /**
60
+ * Creates a random selector.
61
+ * @returns A random selector.
62
+ */
63
+ static random() {
64
+ return EventSelector.fromBuffer(randomBytes(Selector.SIZE));
65
+ }
59
66
  }
60
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXZlbnRfc2VsZWN0b3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYWJpL2V2ZW50X3NlbGVjdG9yLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDaEUsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBRTVDLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUM3RCxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBVXpDLGdGQUFnRjtBQUNoRixNQUFNLE9BQU8sYUFBYyxTQUFRLFFBQVE7SUFDekM7Ozs7T0FJRztJQUNILE1BQU0sQ0FBQyxVQUFVLENBQUMsTUFBNkI7UUFDN0MsTUFBTSxNQUFNLEdBQUcsWUFBWSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUM3QyxNQUFNLEtBQUssR0FBRyxNQUFNLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNsRSxPQUFPLElBQUksYUFBYSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ2xDLENBQUM7SUFFRDs7OztPQUlHO0lBQ0gsTUFBTSxDQUFDLFNBQVMsQ0FBQyxFQUFNO1FBQ3JCLE9BQU8sSUFBSSxhQUFhLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDbEQsQ0FBQztJQUVEOzs7O09BSUc7SUFDSCxNQUFNLENBQUMsYUFBYSxDQUFDLFNBQWlCO1FBQ3BDLHlDQUF5QztRQUN6QyxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQztZQUN6QixNQUFNLElBQUksS0FBSyxDQUFDLHFDQUFxQyxDQUFDLENBQUM7UUFDekQsQ0FBQztRQUNELE9BQU8sYUFBYSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUUsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7SUFDN0YsQ0FBQztJQUVEOzs7Ozs7O09BT0c7SUFDSCxNQUFNLENBQUMsVUFBVSxDQUFDLFFBQWdCO1FBQ2hDLE1BQU0sR0FBRyxHQUFHLE9BQU8sQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUM5QixJQUFJLEdBQUcsQ0FBQyxNQUFNLEtBQUssUUFBUSxDQUFDLElBQUksRUFBRSxDQUFDO1lBQ2pDLE1BQU0sSUFBSSxLQUFLLENBQUMsMkJBQTJCLEdBQUcsQ0FBQyxNQUFNLGNBQWMsUUFBUSxDQUFDLElBQUksSUFBSSxDQUFDLENBQUM7UUFDeEYsQ0FBQztRQUNELE9BQU8sYUFBYSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUN2QyxDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsTUFBTSxDQUFDLEtBQUs7UUFDVixPQUFPLElBQUksYUFBYSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQzlCLENBQUM7Q0FDRiJ9
67
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXZlbnRfc2VsZWN0b3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYWJpL2V2ZW50X3NlbGVjdG9yLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDaEUsT0FBTyxFQUFFLE1BQU0sRUFBRSxXQUFXLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUV6RCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDN0QsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQVV6QyxnRkFBZ0Y7QUFDaEYsTUFBTSxPQUFPLGFBQWMsU0FBUSxRQUFRO0lBQ3pDOzs7O09BSUc7SUFDSCxNQUFNLENBQUMsVUFBVSxDQUFDLE1BQTZCO1FBQzdDLE1BQU0sTUFBTSxHQUFHLFlBQVksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDN0MsTUFBTSxLQUFLLEdBQUcsTUFBTSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDbEUsT0FBTyxJQUFJLGFBQWEsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUNsQyxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNILE1BQU0sQ0FBQyxTQUFTLENBQUMsRUFBTTtRQUNyQixPQUFPLElBQUksYUFBYSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQ2xELENBQUM7SUFFRDs7OztPQUlHO0lBQ0gsTUFBTSxDQUFDLGFBQWEsQ0FBQyxTQUFpQjtRQUNwQyx5Q0FBeUM7UUFDekMsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUM7WUFDekIsTUFBTSxJQUFJLEtBQUssQ0FBQyxxQ0FBcUMsQ0FBQyxDQUFDO1FBQ3pELENBQUM7UUFDRCxPQUFPLGFBQWEsQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxFQUFFLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO0lBQzdGLENBQUM7SUFFRDs7Ozs7OztPQU9HO0lBQ0gsTUFBTSxDQUFDLFVBQVUsQ0FBQyxRQUFnQjtRQUNoQyxNQUFNLEdBQUcsR0FBRyxPQUFPLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDOUIsSUFBSSxHQUFHLENBQUMsTUFBTSxLQUFLLFFBQVEsQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUNqQyxNQUFNLElBQUksS0FBSyxDQUFDLDJCQUEyQixHQUFHLENBQUMsTUFBTSxjQUFjLFFBQVEsQ0FBQyxJQUFJLElBQUksQ0FBQyxDQUFDO1FBQ3hGLENBQUM7UUFDRCxPQUFPLGFBQWEsQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDdkMsQ0FBQztJQUVEOzs7T0FHRztJQUNILE1BQU0sQ0FBQyxLQUFLO1FBQ1YsT0FBTyxJQUFJLGFBQWEsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUM5QixDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsTUFBTSxDQUFDLE1BQU07UUFDWCxPQUFPLGFBQWEsQ0FBQyxVQUFVLENBQUMsV0FBVyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO0lBQzlELENBQUM7Q0FDRiJ9
@@ -1,3 +1,19 @@
1
1
  /// <reference types="node" resolution-mode="require"/>
2
2
  export declare const randomBytes: (len: number) => Buffer;
3
+ /**
4
+ * Generate a random integer less than max.
5
+ * @param max - The maximum value.
6
+ * @returns A random integer.
7
+ *
8
+ * TODO(#3949): This is insecure as it's modulo biased. Nuke or safeguard before mainnet.
9
+ */
10
+ export declare const randomInt: (max: number) => number;
11
+ /**
12
+ * Generate a random bigint less than max.
13
+ * @param max - The maximum value.
14
+ * @returns A random bigint.
15
+ *
16
+ * TODO(#3949): This is insecure as it's modulo biased. Nuke or safeguard before mainnet.
17
+ */
18
+ export declare const randomBigInt: (max: bigint) => bigint;
3
19
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/crypto/random/index.ts"],"names":[],"mappings":";AAiBA,eAAO,MAAM,WAAW,QAAS,MAAM,WAwBtC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/crypto/random/index.ts"],"names":[],"mappings":";AAmBA,eAAO,MAAM,WAAW,QAAS,MAAM,WA8BtC,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,SAAS,QAAS,MAAM,WAIpC,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,YAAY,QAAS,MAAM,WAIvC,CAAC"}
@@ -1,5 +1,6 @@
1
1
  import nodeCrypto from 'crypto';
2
2
  import isNode from 'detect-node';
3
+ import { RandomnessSingleton } from './randomness_singleton.js';
3
4
  // limit of Crypto.getRandomValues()
4
5
  // https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues
5
6
  const MAX_BYTES = 65536;
@@ -13,6 +14,10 @@ const getWebCrypto = () => {
13
14
  return undefined;
14
15
  };
15
16
  export const randomBytes = (len) => {
17
+ const singleton = RandomnessSingleton.getInstance();
18
+ if (singleton.isDeterministic()) {
19
+ return singleton.getBytes(len);
20
+ }
16
21
  if (isNode) {
17
22
  return nodeCrypto.randomBytes(len);
18
23
  }
@@ -35,4 +40,28 @@ export const randomBytes = (len) => {
35
40
  }
36
41
  return buf;
37
42
  };
38
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvY3J5cHRvL3JhbmRvbS9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLFVBQVUsTUFBTSxRQUFRLENBQUM7QUFDaEMsT0FBTyxNQUFNLE1BQU0sYUFBYSxDQUFDO0FBRWpDLG9DQUFvQztBQUNwQywwRUFBMEU7QUFDMUUsTUFBTSxTQUFTLEdBQUcsS0FBSyxDQUFDO0FBRXhCLE1BQU0sWUFBWSxHQUFHLEdBQUcsRUFBRTtJQUN4QixJQUFJLE9BQU8sTUFBTSxLQUFLLFdBQVcsSUFBSSxNQUFNLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDbkQsT0FBTyxNQUFNLENBQUMsTUFBTSxDQUFDO0lBQ3ZCLENBQUM7SUFDRCxJQUFJLE9BQU8sSUFBSSxLQUFLLFdBQVcsSUFBSSxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDL0MsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDO0lBQ3JCLENBQUM7SUFDRCxPQUFPLFNBQVMsQ0FBQztBQUNuQixDQUFDLENBQUM7QUFFRixNQUFNLENBQUMsTUFBTSxXQUFXLEdBQUcsQ0FBQyxHQUFXLEVBQUUsRUFBRTtJQUN6QyxJQUFJLE1BQU0sRUFBRSxDQUFDO1FBQ1gsT0FBTyxVQUFVLENBQUMsV0FBVyxDQUFDLEdBQUcsQ0FBVyxDQUFDO0lBQy9DLENBQUM7SUFFRCxNQUFNLE1BQU0sR0FBRyxZQUFZLEVBQUUsQ0FBQztJQUM5QixJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDWixNQUFNLElBQUksS0FBSyxDQUFDLG9DQUFvQyxDQUFDLENBQUM7SUFDeEQsQ0FBQztJQUVELE1BQU0sR0FBRyxHQUFHLE1BQU0sQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDcEMsSUFBSSxHQUFHLEdBQUcsU0FBUyxFQUFFLENBQUM7UUFDcEIsK0NBQStDO1FBQy9DLG9HQUFvRztRQUNwRyxLQUFLLElBQUksU0FBUyxHQUFHLENBQUMsRUFBRSxTQUFTLEdBQUcsR0FBRyxFQUFFLFNBQVMsSUFBSSxTQUFTLEVBQUUsQ0FBQztZQUNoRSxrRUFBa0U7WUFDbEUsc0NBQXNDO1lBQ3RDLE1BQU0sQ0FBQyxlQUFlLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxTQUFTLEVBQUUsU0FBUyxHQUFHLFNBQVMsQ0FBQyxDQUFDLENBQUM7UUFDdEUsQ0FBQztJQUNILENBQUM7U0FBTSxDQUFDO1FBQ04sTUFBTSxDQUFDLGVBQWUsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUM5QixDQUFDO0lBRUQsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDLENBQUMifQ==
43
+ /**
44
+ * Generate a random integer less than max.
45
+ * @param max - The maximum value.
46
+ * @returns A random integer.
47
+ *
48
+ * TODO(#3949): This is insecure as it's modulo biased. Nuke or safeguard before mainnet.
49
+ */
50
+ export const randomInt = (max) => {
51
+ const randomBuffer = randomBytes(6); // Generate a buffer of 6 random bytes.
52
+ const randomInt = parseInt(randomBuffer.toString('hex'), 16); // Convert buffer to a large integer.
53
+ return randomInt % max; // Use modulo to ensure the result is less than max.
54
+ };
55
+ /**
56
+ * Generate a random bigint less than max.
57
+ * @param max - The maximum value.
58
+ * @returns A random bigint.
59
+ *
60
+ * TODO(#3949): This is insecure as it's modulo biased. Nuke or safeguard before mainnet.
61
+ */
62
+ export const randomBigInt = (max) => {
63
+ const randomBuffer = randomBytes(8); // Generate a buffer of 8 random bytes.
64
+ const randomBigInt = BigInt(`0x${randomBuffer.toString('hex')}`); // Convert buffer to a large integer.
65
+ return randomBigInt % max; // Use modulo to ensure the result is less than max.
66
+ };
67
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvY3J5cHRvL3JhbmRvbS9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLFVBQVUsTUFBTSxRQUFRLENBQUM7QUFDaEMsT0FBTyxNQUFNLE1BQU0sYUFBYSxDQUFDO0FBRWpDLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBRWhFLG9DQUFvQztBQUNwQywwRUFBMEU7QUFDMUUsTUFBTSxTQUFTLEdBQUcsS0FBSyxDQUFDO0FBRXhCLE1BQU0sWUFBWSxHQUFHLEdBQUcsRUFBRTtJQUN4QixJQUFJLE9BQU8sTUFBTSxLQUFLLFdBQVcsSUFBSSxNQUFNLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDbkQsT0FBTyxNQUFNLENBQUMsTUFBTSxDQUFDO0lBQ3ZCLENBQUM7SUFDRCxJQUFJLE9BQU8sSUFBSSxLQUFLLFdBQVcsSUFBSSxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDL0MsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDO0lBQ3JCLENBQUM7SUFDRCxPQUFPLFNBQVMsQ0FBQztBQUNuQixDQUFDLENBQUM7QUFFRixNQUFNLENBQUMsTUFBTSxXQUFXLEdBQUcsQ0FBQyxHQUFXLEVBQUUsRUFBRTtJQUN6QyxNQUFNLFNBQVMsR0FBRyxtQkFBbUIsQ0FBQyxXQUFXLEVBQUUsQ0FBQztJQUVwRCxJQUFJLFNBQVMsQ0FBQyxlQUFlLEVBQUUsRUFBRSxDQUFDO1FBQ2hDLE9BQU8sU0FBUyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUNqQyxDQUFDO0lBRUQsSUFBSSxNQUFNLEVBQUUsQ0FBQztRQUNYLE9BQU8sVUFBVSxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQVcsQ0FBQztJQUMvQyxDQUFDO0lBRUQsTUFBTSxNQUFNLEdBQUcsWUFBWSxFQUFFLENBQUM7SUFDOUIsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQ1osTUFBTSxJQUFJLEtBQUssQ0FBQyxvQ0FBb0MsQ0FBQyxDQUFDO0lBQ3hELENBQUM7SUFFRCxNQUFNLEdBQUcsR0FBRyxNQUFNLENBQUMsV0FBVyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQ3BDLElBQUksR0FBRyxHQUFHLFNBQVMsRUFBRSxDQUFDO1FBQ3BCLCtDQUErQztRQUMvQyxvR0FBb0c7UUFDcEcsS0FBSyxJQUFJLFNBQVMsR0FBRyxDQUFDLEVBQUUsU0FBUyxHQUFHLEdBQUcsRUFBRSxTQUFTLElBQUksU0FBUyxFQUFFLENBQUM7WUFDaEUsa0VBQWtFO1lBQ2xFLHNDQUFzQztZQUN0QyxNQUFNLENBQUMsZUFBZSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsU0FBUyxFQUFFLFNBQVMsR0FBRyxTQUFTLENBQUMsQ0FBQyxDQUFDO1FBQ3RFLENBQUM7SUFDSCxDQUFDO1NBQU0sQ0FBQztRQUNOLE1BQU0sQ0FBQyxlQUFlLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDOUIsQ0FBQztJQUVELE9BQU8sR0FBRyxDQUFDO0FBQ2IsQ0FBQyxDQUFDO0FBRUY7Ozs7OztHQU1HO0FBQ0gsTUFBTSxDQUFDLE1BQU0sU0FBUyxHQUFHLENBQUMsR0FBVyxFQUFFLEVBQUU7SUFDdkMsTUFBTSxZQUFZLEdBQUcsV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsdUNBQXVDO0lBQzVFLE1BQU0sU0FBUyxHQUFHLFFBQVEsQ0FBQyxZQUFZLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMscUNBQXFDO0lBQ25HLE9BQU8sU0FBUyxHQUFHLEdBQUcsQ0FBQyxDQUFDLG9EQUFvRDtBQUM5RSxDQUFDLENBQUM7QUFFRjs7Ozs7O0dBTUc7QUFDSCxNQUFNLENBQUMsTUFBTSxZQUFZLEdBQUcsQ0FBQyxHQUFXLEVBQUUsRUFBRTtJQUMxQyxNQUFNLFlBQVksR0FBRyxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyx1Q0FBdUM7SUFDNUUsTUFBTSxZQUFZLEdBQUcsTUFBTSxDQUFDLEtBQUssWUFBWSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxxQ0FBcUM7SUFDdkcsT0FBTyxZQUFZLEdBQUcsR0FBRyxDQUFDLENBQUMsb0RBQW9EO0FBQ2pGLENBQUMsQ0FBQyJ9
@@ -0,0 +1,24 @@
1
+ /// <reference types="node" resolution-mode="require"/>
2
+ /**
3
+ * A number generator which is used as a source of randomness in the system. If the SEED env variable is set, the
4
+ * generator will be deterministic and will always produce the same sequence of numbers. Otherwise a true randomness
5
+ * sourced by crypto library will be used.
6
+ * @remarks This class was implemented so that tests can be run deterministically.
7
+ *
8
+ * TODO(#3949): This is not safe enough for production and should be made safer or removed before mainnet.
9
+ */
10
+ export declare class RandomnessSingleton {
11
+ private readonly seed?;
12
+ private readonly log;
13
+ private static instance;
14
+ private counter;
15
+ private constructor();
16
+ static getInstance(): RandomnessSingleton;
17
+ /**
18
+ * Indicates whether the generator is deterministic (was seeded) or not.
19
+ * @returns Whether the generator is deterministic.
20
+ */
21
+ isDeterministic(): boolean;
22
+ getBytes(length: number): Buffer;
23
+ }
24
+ //# sourceMappingURL=randomness_singleton.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"randomness_singleton.d.ts","sourceRoot":"","sources":["../../../src/crypto/random/randomness_singleton.ts"],"names":[],"mappings":";AAEA;;;;;;;GAOG;AACH,qBAAa,mBAAmB;IAM5B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC;IACtB,OAAO,CAAC,QAAQ,CAAC,GAAG;IANtB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAsB;IAE7C,OAAO,CAAC,OAAO,CAAK;IAEpB,OAAO;WAYO,WAAW,IAAI,mBAAmB;IAShD;;;OAGG;IACI,eAAe,IAAI,OAAO;IAI1B,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;CAiBxC"}
@@ -0,0 +1,55 @@
1
+ import { createDebugLogger } from '../../log/logger.js';
2
+ /**
3
+ * A number generator which is used as a source of randomness in the system. If the SEED env variable is set, the
4
+ * generator will be deterministic and will always produce the same sequence of numbers. Otherwise a true randomness
5
+ * sourced by crypto library will be used.
6
+ * @remarks This class was implemented so that tests can be run deterministically.
7
+ *
8
+ * TODO(#3949): This is not safe enough for production and should be made safer or removed before mainnet.
9
+ */
10
+ export class RandomnessSingleton {
11
+ constructor(seed, log = createDebugLogger('aztec:randomness_singleton')) {
12
+ this.seed = seed;
13
+ this.log = log;
14
+ this.counter = 0;
15
+ if (seed !== undefined) {
16
+ this.log(`Using pseudo-randomness with seed: ${seed}`);
17
+ this.counter = seed;
18
+ }
19
+ else {
20
+ this.log('Using true randomness');
21
+ }
22
+ }
23
+ static getInstance() {
24
+ if (!RandomnessSingleton.instance) {
25
+ const seed = process.env.SEED ? Number(process.env.SEED) : undefined;
26
+ RandomnessSingleton.instance = new RandomnessSingleton(seed);
27
+ }
28
+ return RandomnessSingleton.instance;
29
+ }
30
+ /**
31
+ * Indicates whether the generator is deterministic (was seeded) or not.
32
+ * @returns Whether the generator is deterministic.
33
+ */
34
+ isDeterministic() {
35
+ return this.seed !== undefined;
36
+ }
37
+ getBytes(length) {
38
+ if (this.seed === undefined) {
39
+ // Note: It would be more natural to just have the contents of randomBytes(...) function from
40
+ // yarn-project/foundation/src/crypto/random/index.ts here but that would result in a larger
41
+ // refactor so I think prohibiting use of this func when the seed is undefined is and handling
42
+ // the singleton within randomBytes func is fine.
43
+ throw new Error('RandomnessSingleton is not implemented for non-deterministic mode');
44
+ }
45
+ const result = Buffer.alloc(length);
46
+ for (let i = 0; i < length; i++) {
47
+ // Each byte of the buffer is set to a 1 byte of this.counter's value. 0xff is 255 in decimal and it's used as
48
+ // a mask to get the last 8 bits of the shifted counter.
49
+ result[i] = (this.counter >> (i * 8)) & 0xff;
50
+ }
51
+ this.counter++;
52
+ return result;
53
+ }
54
+ }
55
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmFuZG9tbmVzc19zaW5nbGV0b24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvY3J5cHRvL3JhbmRvbS9yYW5kb21uZXNzX3NpbmdsZXRvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUV4RDs7Ozs7OztHQU9HO0FBQ0gsTUFBTSxPQUFPLG1CQUFtQjtJQUs5QixZQUNtQixJQUFhLEVBQ2IsTUFBTSxpQkFBaUIsQ0FBQyw0QkFBNEIsQ0FBQztRQURyRCxTQUFJLEdBQUosSUFBSSxDQUFTO1FBQ2IsUUFBRyxHQUFILEdBQUcsQ0FBa0Q7UUFKaEUsWUFBTyxHQUFHLENBQUMsQ0FBQztRQU1sQixJQUFJLElBQUksS0FBSyxTQUFTLEVBQUUsQ0FBQztZQUN2QixJQUFJLENBQUMsR0FBRyxDQUFDLHNDQUFzQyxJQUFJLEVBQUUsQ0FBQyxDQUFDO1lBQ3ZELElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDO1FBQ3RCLENBQUM7YUFBTSxDQUFDO1lBQ04sSUFBSSxDQUFDLEdBQUcsQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDO1FBQ3BDLENBQUM7SUFDSCxDQUFDO0lBRU0sTUFBTSxDQUFDLFdBQVc7UUFDdkIsSUFBSSxDQUFDLG1CQUFtQixDQUFDLFFBQVEsRUFBRSxDQUFDO1lBQ2xDLE1BQU0sSUFBSSxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO1lBQ3JFLG1CQUFtQixDQUFDLFFBQVEsR0FBRyxJQUFJLG1CQUFtQixDQUFDLElBQUksQ0FBQyxDQUFDO1FBQy9ELENBQUM7UUFFRCxPQUFPLG1CQUFtQixDQUFDLFFBQVEsQ0FBQztJQUN0QyxDQUFDO0lBRUQ7OztPQUdHO0lBQ0ksZUFBZTtRQUNwQixPQUFPLElBQUksQ0FBQyxJQUFJLEtBQUssU0FBUyxDQUFDO0lBQ2pDLENBQUM7SUFFTSxRQUFRLENBQUMsTUFBYztRQUM1QixJQUFJLElBQUksQ0FBQyxJQUFJLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDNUIsNkZBQTZGO1lBQzdGLDRGQUE0RjtZQUM1Riw4RkFBOEY7WUFDOUYsaURBQWlEO1lBQ2pELE1BQU0sSUFBSSxLQUFLLENBQUMsbUVBQW1FLENBQUMsQ0FBQztRQUN2RixDQUFDO1FBQ0QsTUFBTSxNQUFNLEdBQUcsTUFBTSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUNwQyxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7WUFDaEMsOEdBQThHO1lBQzlHLHdEQUF3RDtZQUN4RCxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsT0FBTyxJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDO1FBQy9DLENBQUM7UUFDRCxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDZixPQUFPLE1BQU0sQ0FBQztJQUNoQixDQUFDO0NBQ0YifQ==
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aztec/foundation",
3
- "version": "0.27.1",
3
+ "version": "0.27.2",
4
4
  "packageManager": "yarn@3.4.1",
5
5
  "type": "module",
6
6
  "main": "./dest/index.js",
@@ -61,7 +61,7 @@
61
61
  "rootDir": "./src"
62
62
  },
63
63
  "dependencies": {
64
- "@aztec/bb.js": "0.27.1",
64
+ "@aztec/bb.js": "0.27.2",
65
65
  "@koa/cors": "^4.0.0",
66
66
  "@noble/curves": "^1.2.0",
67
67
  "bn.js": "^5.2.1",
@@ -1,5 +1,5 @@
1
1
  import { fromHex, toBigIntBE } from '../bigint-buffer/index.js';
2
- import { keccak } from '../crypto/index.js';
2
+ import { keccak, randomBytes } from '../crypto/index.js';
3
3
  import { Fr } from '../fields/fields.js';
4
4
  import { BufferReader } from '../serialize/buffer_reader.js';
5
5
  import { Selector } from './selector.js';
@@ -70,4 +70,12 @@ export class EventSelector extends Selector {
70
70
  static empty() {
71
71
  return new EventSelector(0);
72
72
  }
73
+
74
+ /**
75
+ * Creates a random selector.
76
+ * @returns A random selector.
77
+ */
78
+ static random() {
79
+ return EventSelector.fromBuffer(randomBytes(Selector.SIZE));
80
+ }
73
81
  }
@@ -1,6 +1,8 @@
1
1
  import nodeCrypto from 'crypto';
2
2
  import isNode from 'detect-node';
3
3
 
4
+ import { RandomnessSingleton } from './randomness_singleton.js';
5
+
4
6
  // limit of Crypto.getRandomValues()
5
7
  // https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues
6
8
  const MAX_BYTES = 65536;
@@ -16,6 +18,12 @@ const getWebCrypto = () => {
16
18
  };
17
19
 
18
20
  export const randomBytes = (len: number) => {
21
+ const singleton = RandomnessSingleton.getInstance();
22
+
23
+ if (singleton.isDeterministic()) {
24
+ return singleton.getBytes(len);
25
+ }
26
+
19
27
  if (isNode) {
20
28
  return nodeCrypto.randomBytes(len) as Buffer;
21
29
  }
@@ -40,3 +48,29 @@ export const randomBytes = (len: number) => {
40
48
 
41
49
  return buf;
42
50
  };
51
+
52
+ /**
53
+ * Generate a random integer less than max.
54
+ * @param max - The maximum value.
55
+ * @returns A random integer.
56
+ *
57
+ * TODO(#3949): This is insecure as it's modulo biased. Nuke or safeguard before mainnet.
58
+ */
59
+ export const randomInt = (max: number) => {
60
+ const randomBuffer = randomBytes(6); // Generate a buffer of 6 random bytes.
61
+ const randomInt = parseInt(randomBuffer.toString('hex'), 16); // Convert buffer to a large integer.
62
+ return randomInt % max; // Use modulo to ensure the result is less than max.
63
+ };
64
+
65
+ /**
66
+ * Generate a random bigint less than max.
67
+ * @param max - The maximum value.
68
+ * @returns A random bigint.
69
+ *
70
+ * TODO(#3949): This is insecure as it's modulo biased. Nuke or safeguard before mainnet.
71
+ */
72
+ export const randomBigInt = (max: bigint) => {
73
+ const randomBuffer = randomBytes(8); // Generate a buffer of 8 random bytes.
74
+ const randomBigInt = BigInt(`0x${randomBuffer.toString('hex')}`); // Convert buffer to a large integer.
75
+ return randomBigInt % max; // Use modulo to ensure the result is less than max.
76
+ };
@@ -0,0 +1,62 @@
1
+ import { createDebugLogger } from '../../log/logger.js';
2
+
3
+ /**
4
+ * A number generator which is used as a source of randomness in the system. If the SEED env variable is set, the
5
+ * generator will be deterministic and will always produce the same sequence of numbers. Otherwise a true randomness
6
+ * sourced by crypto library will be used.
7
+ * @remarks This class was implemented so that tests can be run deterministically.
8
+ *
9
+ * TODO(#3949): This is not safe enough for production and should be made safer or removed before mainnet.
10
+ */
11
+ export class RandomnessSingleton {
12
+ private static instance: RandomnessSingleton;
13
+
14
+ private counter = 0;
15
+
16
+ private constructor(
17
+ private readonly seed?: number,
18
+ private readonly log = createDebugLogger('aztec:randomness_singleton'),
19
+ ) {
20
+ if (seed !== undefined) {
21
+ this.log(`Using pseudo-randomness with seed: ${seed}`);
22
+ this.counter = seed;
23
+ } else {
24
+ this.log('Using true randomness');
25
+ }
26
+ }
27
+
28
+ public static getInstance(): RandomnessSingleton {
29
+ if (!RandomnessSingleton.instance) {
30
+ const seed = process.env.SEED ? Number(process.env.SEED) : undefined;
31
+ RandomnessSingleton.instance = new RandomnessSingleton(seed);
32
+ }
33
+
34
+ return RandomnessSingleton.instance;
35
+ }
36
+
37
+ /**
38
+ * Indicates whether the generator is deterministic (was seeded) or not.
39
+ * @returns Whether the generator is deterministic.
40
+ */
41
+ public isDeterministic(): boolean {
42
+ return this.seed !== undefined;
43
+ }
44
+
45
+ public getBytes(length: number): Buffer {
46
+ if (this.seed === undefined) {
47
+ // Note: It would be more natural to just have the contents of randomBytes(...) function from
48
+ // yarn-project/foundation/src/crypto/random/index.ts here but that would result in a larger
49
+ // refactor so I think prohibiting use of this func when the seed is undefined is and handling
50
+ // the singleton within randomBytes func is fine.
51
+ throw new Error('RandomnessSingleton is not implemented for non-deterministic mode');
52
+ }
53
+ const result = Buffer.alloc(length);
54
+ for (let i = 0; i < length; i++) {
55
+ // Each byte of the buffer is set to a 1 byte of this.counter's value. 0xff is 255 in decimal and it's used as
56
+ // a mask to get the last 8 bits of the shifted counter.
57
+ result[i] = (this.counter >> (i * 8)) & 0xff;
58
+ }
59
+ this.counter++;
60
+ return result;
61
+ }
62
+ }