@typeberry/lib 0.5.2-9afefa7 → 0.5.2-ff62cc9

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@typeberry/lib",
3
- "version": "0.5.2-9afefa7",
3
+ "version": "0.5.2-ff62cc9",
4
4
  "description": "Typeberry Library",
5
5
  "main": "./bin/lib/index.js",
6
6
  "types": "./bin/lib/index.d.ts",
@@ -8,12 +8,14 @@ import { type Opaque, Result } from "#@typeberry/utils";
8
8
  import type { BandernsatchWasm } from "./bandersnatch-wasm.js";
9
9
  declare const FUNCTIONS: {
10
10
  verifySeal: typeof verifySeal;
11
+ verifyHeaderSeals: typeof verifyHeaderSeals;
11
12
  verifyTickets: typeof verifyTickets;
12
13
  getRingCommitment: typeof getRingCommitment;
13
14
  generateSeal: typeof generateSeal;
14
15
  getVrfOutputHash: typeof getVrfOutputHash;
15
16
  };
16
17
  export default FUNCTIONS;
18
+ declare function verifyHeaderSeals(bandersnatch: BandernsatchWasm, authorKey: BandersnatchKey, signature: BandersnatchVrfSignature, payload: BytesBlob, encodedUnsealedHeader: BytesBlob, entropySignature: BandersnatchVrfSignature, entropyPayloadPrefix: BytesBlob): Promise<Result<[EntropyHash, EntropyHash], null>>;
17
19
  declare function verifySeal(bandersnatch: BandernsatchWasm, authorKey: BandersnatchKey, signature: BandersnatchVrfSignature, payload: BytesBlob, encodedUnsealedHeader: BytesBlob): Promise<Result<EntropyHash, null>>;
18
20
  declare function getRingCommitment(bandersnatch: BandernsatchWasm, validators: BandersnatchKey[]): Promise<Result<BandersnatchRingRoot, null>>;
19
21
  declare function verifyTickets(bandersnatch: BandernsatchWasm, numberOfValidators: number, epochRoot: BandersnatchRingRoot, tickets: readonly SignedTicket[], entropy: EntropyHash): Promise<{
@@ -1 +1 @@
1
- {"version":3,"file":"bandersnatch-vrf.d.ts","sourceRoot":"","sources":["../../../../../packages/jam/safrole/bandersnatch-vrf.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,EAAS,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,KAAK,EAAE,eAAe,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AACjF,OAAO,EAGL,KAAK,oBAAoB,EACzB,KAAK,wBAAwB,EAC9B,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAAa,KAAK,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7D,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAwB/D,QAAA,MAAM,SAAS;;;;;;CAMd,CAAC;AAKF,eAAe,SAAS,CAAC;AAEzB,iBAAe,UAAU,CACvB,YAAY,EAAE,gBAAgB,EAC9B,SAAS,EAAE,eAAe,EAC1B,SAAS,EAAE,wBAAwB,EACnC,OAAO,EAAE,SAAS,EAClB,qBAAqB,EAAE,SAAS,GAC/B,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC,CAapC;AAED,iBAAS,iBAAiB,CACxB,YAAY,EAAE,gBAAgB,EAC9B,UAAU,EAAE,eAAe,EAAE,GAC5B,OAAO,CAAC,MAAM,CAAC,oBAAoB,EAAE,IAAI,CAAC,CAAC,CAmB7C;AAkBD,iBAAe,aAAa,CAC1B,YAAY,EAAE,gBAAgB,EAC9B,kBAAkB,EAAE,MAAM,EAC1B,SAAS,EAAE,oBAAoB,EAC/B,OAAO,EAAE,SAAS,YAAY,EAAE,EAChC,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,WAAW,EAAE,WAAW,CAAA;CAAE,EAAE,CAAC,CAqB3D;AAED,iBAAe,YAAY,CACzB,YAAY,EAAE,gBAAgB,EAC9B,SAAS,EAAE,sBAAsB,EACjC,KAAK,EAAE,SAAS,EAChB,OAAO,EAAE,SAAS,GACjB,OAAO,CAAC,MAAM,CAAC,wBAAwB,EAAE,IAAI,CAAC,CAAC,CAQjD;AAED,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,UAAU,EAAE,iBAAiB,CAAC,CAAC;AAElE,iBAAe,gBAAgB,CAC7B,YAAY,EAAE,gBAAgB,EAC9B,SAAS,EAAE,sBAAsB,EACjC,KAAK,EAAE,SAAS,GACf,OAAO,CAAC,MAAM,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC,CAQtC"}
1
+ {"version":3,"file":"bandersnatch-vrf.d.ts","sourceRoot":"","sources":["../../../../../packages/jam/safrole/bandersnatch-vrf.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,EAAS,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,KAAK,EAAE,eAAe,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AACjF,OAAO,EAGL,KAAK,oBAAoB,EACzB,KAAK,wBAAwB,EAC9B,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAAa,KAAK,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7D,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAwB/D,QAAA,MAAM,SAAS;;;;;;;CAOd,CAAC;AAKF,eAAe,SAAS,CAAC;AAEzB,iBAAe,iBAAiB,CAC9B,YAAY,EAAE,gBAAgB,EAC9B,SAAS,EAAE,eAAe,EAC1B,SAAS,EAAE,wBAAwB,EACnC,OAAO,EAAE,SAAS,EAClB,qBAAqB,EAAE,SAAS,EAChC,gBAAgB,EAAE,wBAAwB,EAC1C,oBAAoB,EAAE,SAAS,GAC9B,OAAO,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,WAAW,CAAC,EAAE,IAAI,CAAC,CAAC,CAkBnD;AAED,iBAAe,UAAU,CACvB,YAAY,EAAE,gBAAgB,EAC9B,SAAS,EAAE,eAAe,EAC1B,SAAS,EAAE,wBAAwB,EACnC,OAAO,EAAE,SAAS,EAClB,qBAAqB,EAAE,SAAS,GAC/B,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC,CAapC;AAED,iBAAS,iBAAiB,CACxB,YAAY,EAAE,gBAAgB,EAC9B,UAAU,EAAE,eAAe,EAAE,GAC5B,OAAO,CAAC,MAAM,CAAC,oBAAoB,EAAE,IAAI,CAAC,CAAC,CAmB7C;AAkBD,iBAAe,aAAa,CAC1B,YAAY,EAAE,gBAAgB,EAC9B,kBAAkB,EAAE,MAAM,EAC1B,SAAS,EAAE,oBAAoB,EAC/B,OAAO,EAAE,SAAS,YAAY,EAAE,EAChC,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,WAAW,EAAE,WAAW,CAAA;CAAE,EAAE,CAAC,CAqB3D;AAED,iBAAe,YAAY,CACzB,YAAY,EAAE,gBAAgB,EAC9B,SAAS,EAAE,sBAAsB,EACjC,KAAK,EAAE,SAAS,EAChB,OAAO,EAAE,SAAS,GACjB,OAAO,CAAC,MAAM,CAAC,wBAAwB,EAAE,IAAI,CAAC,CAAC,CAQjD;AAED,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,UAAU,EAAE,iBAAiB,CAAC,CAAC;AAElE,iBAAe,gBAAgB,CAC7B,YAAY,EAAE,gBAAgB,EAC9B,SAAS,EAAE,sBAAsB,EACjC,KAAK,EAAE,SAAS,GACf,OAAO,CAAC,MAAM,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC,CAQtC"}
@@ -20,6 +20,7 @@ var ResultValues;
20
20
  const ringCommitmentCache = [];
21
21
  const FUNCTIONS = {
22
22
  verifySeal,
23
+ verifyHeaderSeals,
23
24
  verifyTickets,
24
25
  getRingCommitment,
25
26
  generateSeal,
@@ -29,6 +30,16 @@ const FUNCTIONS = {
29
30
  // Ideally we would just export functions and figure out how to mock
30
31
  // properly in ESM.
31
32
  export default FUNCTIONS;
33
+ async function verifyHeaderSeals(bandersnatch, authorKey, signature, payload, encodedUnsealedHeader, entropySignature, entropyPayloadPrefix) {
34
+ const sealResult = await bandersnatch.verifyHeaderSeals(authorKey.raw, signature.raw, payload.raw, encodedUnsealedHeader.raw, entropySignature.raw, entropyPayloadPrefix.raw);
35
+ if (sealResult[RESULT_INDEX] === ResultValues.Error) {
36
+ return Result.error(null, () => "Bandersnatch VRF seal verification failed");
37
+ }
38
+ return Result.ok([
39
+ Bytes.fromBlob(sealResult.subarray(1, 33), HASH_SIZE).asOpaque(),
40
+ Bytes.fromBlob(sealResult.subarray(33), HASH_SIZE).asOpaque(),
41
+ ]);
42
+ }
32
43
  async function verifySeal(bandersnatch, authorKey, signature, payload, encodedUnsealedHeader) {
33
44
  const sealResult = await bandersnatch.verifySeal(authorKey.raw, signature.raw, payload.raw, encodedUnsealedHeader.raw);
34
45
  if (sealResult[RESULT_INDEX] === ResultValues.Error) {
@@ -2,6 +2,7 @@ export declare class BandernsatchWasm {
2
2
  private constructor();
3
3
  static new(): Promise<BandernsatchWasm>;
4
4
  verifySeal(authorKey: Uint8Array, signature: Uint8Array, payload: Uint8Array, auxData: Uint8Array): Promise<Uint8Array<ArrayBufferLike>>;
5
+ verifyHeaderSeals(authorKey: Uint8Array, headerSeal: Uint8Array, headerSealPayload: Uint8Array, unsealedHeader: Uint8Array, entropySeal: Uint8Array, entropyPayloadPrefix: Uint8Array): Promise<Uint8Array<ArrayBufferLike>>;
5
6
  getRingCommitment(keys: Uint8Array): Promise<Uint8Array<ArrayBufferLike>>;
6
7
  batchVerifyTicket(ringSize: number, commitment: Uint8Array, ticketsData: Uint8Array, contextLength: number): Promise<Uint8Array<ArrayBufferLike>>;
7
8
  generateSeal(authorKey: Uint8Array, input: Uint8Array, auxData: Uint8Array): Promise<Uint8Array<ArrayBufferLike>>;
@@ -1 +1 @@
1
- {"version":3,"file":"bandersnatch-wasm.d.ts","sourceRoot":"","sources":["../../../../../packages/jam/safrole/bandersnatch-wasm.ts"],"names":[],"mappings":"AAEA,qBAAa,gBAAgB;IAC3B,OAAO;WAEM,GAAG;IAKV,UAAU,CAAC,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,UAAU;IAIjG,iBAAiB,CAAC,IAAI,EAAE,UAAU;IAIlC,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM;IAI1G,YAAY,CAAC,SAAS,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,UAAU;IAI1E,gBAAgB,CAAC,SAAS,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU;CAGhE"}
1
+ {"version":3,"file":"bandersnatch-wasm.d.ts","sourceRoot":"","sources":["../../../../../packages/jam/safrole/bandersnatch-wasm.ts"],"names":[],"mappings":"AAEA,qBAAa,gBAAgB;IAC3B,OAAO;WAEM,GAAG;IAKV,UAAU,CAAC,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,UAAU;IAIjG,iBAAiB,CACrB,SAAS,EAAE,UAAU,EACrB,UAAU,EAAE,UAAU,EACtB,iBAAiB,EAAE,UAAU,EAC7B,cAAc,EAAE,UAAU,EAC1B,WAAW,EAAE,UAAU,EACvB,oBAAoB,EAAE,UAAU;IAY5B,iBAAiB,CAAC,IAAI,EAAE,UAAU;IAIlC,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM;IAI1G,YAAY,CAAC,SAAS,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,UAAU;IAI1E,gBAAgB,CAAC,SAAS,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU;CAGhE"}
@@ -8,6 +8,9 @@ export class BandernsatchWasm {
8
8
  async verifySeal(authorKey, signature, payload, auxData) {
9
9
  return bandersnatchWasm.verify_seal(authorKey, signature, payload, auxData);
10
10
  }
11
+ async verifyHeaderSeals(authorKey, headerSeal, headerSealPayload, unsealedHeader, entropySeal, entropyPayloadPrefix) {
12
+ return bandersnatchWasm.verify_header_seals(authorKey, headerSeal, headerSealPayload, unsealedHeader, entropySeal, entropyPayloadPrefix);
13
+ }
11
14
  async getRingCommitment(keys) {
12
15
  return bandersnatchWasm.ring_commitment(keys);
13
16
  }
@@ -8,8 +8,7 @@ export declare enum SafroleSealError {
8
8
  InvalidValidatorIndex = 0,
9
9
  InvalidValidator = 1,
10
10
  InvalidTicket = 2,
11
- IncorrectSeal = 3,
12
- IncorrectEntropySource = 4
11
+ IncorrectSeal = 3
13
12
  }
14
13
  export type SafroleSealState = Pick<State, "currentValidatorData" | "sealingKeySeries"> & {
15
14
  currentEntropy: EntropyHash;
@@ -22,7 +21,6 @@ export declare class SafroleSeal {
22
21
  * hence the state is passed as an argument for more control.
23
22
  */
24
23
  verifyHeaderSeal(headerView: HeaderView, state: SafroleSealState): Promise<Result<EntropyHash, SafroleSealError>>;
25
- private verifySeal;
26
24
  /** Regular (non-fallback) mode of Safrole. */
27
25
  verifySealWithTicket(tickets: PerEpochBlock<Ticket>, timeSlot: TimeSlot, entropy: EntropyHash, validatorData: ValidatorData, headerView: HeaderView): Promise<Result<EntropyHash, SafroleSealError>>;
28
26
  /** Fallback mode of Safrole. */
@@ -1 +1 @@
1
- {"version":3,"file":"safrole-seal.d.ts","sourceRoot":"","sources":["../../../../../packages/jam/safrole/safrole-seal.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,WAAW,EAEhB,KAAK,UAAU,EACf,KAAK,aAAa,EAClB,KAAK,QAAQ,EACd,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,6BAA6B,CAAC;AAE1D,OAAO,EAA0B,KAAK,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACjF,OAAO,KAAK,EAAE,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAE7D,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAE1C,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAG1D,oBAAY,gBAAgB;IAC1B,qBAAqB,IAAI;IACzB,gBAAgB,IAAI;IACpB,aAAa,IAAI;IACjB,aAAa,IAAI;IACjB,sBAAsB,IAAI;CAC3B;AAED,MAAM,MAAM,gBAAgB,GAAG,IAAI,CAAC,KAAK,EAAE,sBAAsB,GAAG,kBAAkB,CAAC,GAAG;IACxF,cAAc,EAAE,WAAW,CAAC;CAC7B,CAAC;AAIF,qBAAa,WAAW;IACV,OAAO,CAAC,QAAQ,CAAC,YAAY;gBAAZ,YAAY,GAAE,OAAO,CAAC,gBAAgB,CAA0B;IAC7F;;;OAGG;IACG,gBAAgB,CACpB,UAAU,EAAE,UAAU,EACtB,KAAK,EAAE,gBAAgB,GACtB,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,gBAAgB,CAAC,CAAC;YA6BnC,UAAU;IA0BxB,8CAA8C;IACxC,oBAAoB,CACxB,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,EAC9B,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,WAAW,EACpB,aAAa,EAAE,aAAa,EAC5B,UAAU,EAAE,UAAU,GACrB,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,gBAAgB,CAAC,CAAC;IA4BjD,gCAAgC;IAC1B,kBAAkB,CACtB,IAAI,EAAE,aAAa,CAAC,eAAe,CAAC,EACpC,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,WAAW,EACpB,SAAS,EAAE,aAAa,EACxB,UAAU,EAAE,UAAU,GACrB,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,gBAAgB,CAAC,CAAC;CA2BlD"}
1
+ {"version":3,"file":"safrole-seal.d.ts","sourceRoot":"","sources":["../../../../../packages/jam/safrole/safrole-seal.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,WAAW,EAEhB,KAAK,UAAU,EACf,KAAK,aAAa,EAClB,KAAK,QAAQ,EACd,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,6BAA6B,CAAC;AAE1D,OAAO,EAA0B,KAAK,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACjF,OAAO,KAAK,EAAE,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAE7D,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAE1C,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAG1D,oBAAY,gBAAgB;IAC1B,qBAAqB,IAAI;IACzB,gBAAgB,IAAI;IACpB,aAAa,IAAI;IACjB,aAAa,IAAI;CAClB;AAED,MAAM,MAAM,gBAAgB,GAAG,IAAI,CAAC,KAAK,EAAE,sBAAsB,GAAG,kBAAkB,CAAC,GAAG;IACxF,cAAc,EAAE,WAAW,CAAC;CAC7B,CAAC;AAIF,qBAAa,WAAW;IACV,OAAO,CAAC,QAAQ,CAAC,YAAY;gBAAZ,YAAY,GAAE,OAAO,CAAC,gBAAgB,CAA0B;IAC7F;;;OAGG;IACG,gBAAgB,CACpB,UAAU,EAAE,UAAU,EACtB,KAAK,EAAE,gBAAgB,GACtB,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,gBAAgB,CAAC,CAAC;IAuBjD,8CAA8C;IACxC,oBAAoB,CACxB,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,EAC9B,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,WAAW,EACpB,aAAa,EAAE,aAAa,EAC5B,UAAU,EAAE,UAAU,GACrB,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,gBAAgB,CAAC,CAAC;IAmCjD,gCAAgC;IAC1B,kBAAkB,CACtB,IAAI,EAAE,aAAa,CAAC,eAAe,CAAC,EACpC,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,WAAW,EACpB,SAAS,EAAE,aAAa,EACxB,UAAU,EAAE,UAAU,GACrB,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,gBAAgB,CAAC,CAAC;CA8BlD"}
@@ -12,7 +12,6 @@ export var SafroleSealError;
12
12
  SafroleSealError[SafroleSealError["InvalidValidator"] = 1] = "InvalidValidator";
13
13
  SafroleSealError[SafroleSealError["InvalidTicket"] = 2] = "InvalidTicket";
14
14
  SafroleSealError[SafroleSealError["IncorrectSeal"] = 3] = "IncorrectSeal";
15
- SafroleSealError[SafroleSealError["IncorrectEntropySource"] = 4] = "IncorrectEntropySource";
16
15
  })(SafroleSealError || (SafroleSealError = {}));
17
16
  const BANDERSNATCH_ZERO_KEY = Bytes.zero(BANDERSNATCH_KEY_BYTES).asOpaque();
18
17
  export class SafroleSeal {
@@ -25,21 +24,6 @@ export class SafroleSeal {
25
24
  * hence the state is passed as an argument for more control.
26
25
  */
27
26
  async verifyHeaderSeal(headerView, state) {
28
- const sealResult = await this.verifySeal(headerView, state);
29
- if (sealResult.isError) {
30
- return sealResult;
31
- }
32
- // verify entropySource
33
- const payload = BytesBlob.blobFromParts(JAM_ENTROPY, sealResult.ok.raw);
34
- const blockAuthorIndex = headerView.bandersnatchBlockAuthorIndex.materialize();
35
- const blockAuthorKey = state.currentValidatorData.at(blockAuthorIndex)?.bandersnatch;
36
- const entropySourceResult = await bandersnatchVrf.verifySeal(await this.bandersnatch, blockAuthorKey ?? BANDERSNATCH_ZERO_KEY, headerView.entropySource.materialize(), payload, BytesBlob.blobFromNumbers([]));
37
- if (entropySourceResult.isError) {
38
- return Result.error(SafroleSealError.IncorrectEntropySource, () => "Safrole: incorrect entropy source in header seal");
39
- }
40
- return Result.ok(entropySourceResult.ok);
41
- }
42
- async verifySeal(headerView, state) {
43
27
  // we use transitioned keys already
44
28
  const validatorIndex = headerView.bandersnatchBlockAuthorIndex.materialize();
45
29
  const authorKeys = state.currentValidatorData.at(validatorIndex);
@@ -58,17 +42,21 @@ export class SafroleSeal {
58
42
  async verifySealWithTicket(tickets, timeSlot, entropy, validatorData, headerView) {
59
43
  const index = timeSlot % tickets.length;
60
44
  const ticket = tickets.at(index);
61
- const payload = BytesBlob.blobFromParts(JAM_TICKET_SEAL, entropy.raw, new Uint8Array([ticket?.attempt ?? 0]));
62
- // verify seal correctness
45
+ if (ticket === undefined) {
46
+ return Result.error(SafroleSealError.IncorrectSeal, () => "Safrole: missing ticket");
47
+ }
48
+ const payload = BytesBlob.blobFromParts(JAM_TICKET_SEAL, entropy.raw, new Uint8Array([ticket.attempt]));
49
+ // verify seal and entropy source correctness
63
50
  const authorKey = validatorData.bandersnatch;
64
- const result = await bandersnatchVrf.verifySeal(await this.bandersnatch, authorKey ?? BANDERSNATCH_ZERO_KEY, headerView.seal.materialize(), payload, encodeUnsealedHeader(headerView));
51
+ const result = await bandersnatchVrf.verifyHeaderSeals(await this.bandersnatch, authorKey ?? BANDERSNATCH_ZERO_KEY, headerView.seal.materialize(), payload, encodeUnsealedHeader(headerView), headerView.entropySource.materialize(), BytesBlob.blobFrom(JAM_ENTROPY));
65
52
  if (result.isError) {
66
53
  return Result.error(SafroleSealError.IncorrectSeal, () => "Safrole: incorrect seal with ticket");
67
54
  }
68
- if (ticket === undefined || !ticket.id.isEqualTo(result.ok)) {
69
- return Result.error(SafroleSealError.InvalidTicket, () => `Safrole: invalid ticket, expected ${ticket?.id} got ${result.ok}`);
55
+ const [sealOutput, entropyOutput] = result.ok;
56
+ if (!ticket.id.isEqualTo(sealOutput)) {
57
+ return Result.error(SafroleSealError.InvalidTicket, () => `Safrole: invalid ticket, expected ${ticket.id} got ${sealOutput}`);
70
58
  }
71
- return Result.ok(result.ok);
59
+ return Result.ok(entropyOutput);
72
60
  }
73
61
  /** Fallback mode of Safrole. */
74
62
  async verifySealWithKeys(keys, timeSlot, entropy, authorKey, headerView) {
@@ -78,12 +66,13 @@ export class SafroleSeal {
78
66
  if (sealingKey === undefined || !sealingKey.isEqualTo(authorBandersnatchKey)) {
79
67
  return Result.error(SafroleSealError.InvalidValidator, () => `Invalid Validator. Expected: ${sealingKey}, got: ${authorKey.bandersnatch}`);
80
68
  }
81
- // verify seal correctness
69
+ // verify seal and entropy source correctness
82
70
  const payload = BytesBlob.blobFromParts(JAM_FALLBACK_SEAL, entropy.raw);
83
- const result = await bandersnatchVrf.verifySeal(await this.bandersnatch, authorBandersnatchKey, headerView.seal.materialize(), payload, encodeUnsealedHeader(headerView));
71
+ const result = await bandersnatchVrf.verifyHeaderSeals(await this.bandersnatch, authorBandersnatchKey, headerView.seal.materialize(), payload, encodeUnsealedHeader(headerView), headerView.entropySource.materialize(), BytesBlob.blobFrom(JAM_ENTROPY));
84
72
  if (result.isError) {
85
73
  return Result.error(SafroleSealError.IncorrectSeal, () => "Safrole: incorrect seal with keys");
86
74
  }
87
- return Result.ok(result.ok);
75
+ const [_, entropyOutput] = result.ok;
76
+ return Result.ok(entropyOutput);
88
77
  }
89
78
  }