Skip to content

Commit

Permalink
check the round on returned beacons
Browse files Browse the repository at this point in the history
  • Loading branch information
CluEleSsUK committed Dec 11, 2023
1 parent 5d7faa5 commit c708e9d
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 18 deletions.
8 changes: 6 additions & 2 deletions lib/beacon-verification.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,16 @@ import {
G2UnchainedBeacon,
isG1G2SwappedBeacon,
G1UnchainedBeacon,
isG1Rfc9380
isG1Rfc9380, roundAt

Check failure on line 19 in lib/beacon-verification.ts

View workflow job for this annotation

GitHub Actions / build_test_and_publish

'roundAt' is defined but never used
} from './index'

async function verifyBeacon(chainInfo: ChainInfo, beacon: RandomnessBeacon): Promise<boolean> {
async function verifyBeacon(chainInfo: ChainInfo, beacon: RandomnessBeacon, expectedRound: number): Promise<boolean> {
const publicKey = chainInfo.public_key

if (beacon.round !== expectedRound) {
return false
}

if (!await randomnessIsValid(beacon)) {
return false
}
Expand Down
10 changes: 6 additions & 4 deletions lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,9 @@ export async function fetchBeacon(client: ChainClient, roundNumber?: number): Pr
beacon = await client.get(roundNumber)
}

return validatedBeacon(client, beacon)
const expectedRound = roundAt(Date.now(), await client.chain().info())

return validatedBeacon(client, beacon, expectedRound)
}

// fetch the most recent beacon to have been emitted at a given `time` in epoch ms
Expand All @@ -101,7 +103,7 @@ export async function* watch(
await sleep(roundTime(info, currentRound) - now)

const beacon = await retryOnError(async () => client.get(currentRound), options.retriesOnFailure)
yield validatedBeacon(client, beacon)
yield validatedBeacon(client, beacon, currentRound)
currentRound = currentRound + 1
}
}
Expand All @@ -118,12 +120,12 @@ const defaultWatchOptions = {
}

// internal function for validating a beacon if validation has not been disabled in the client options
async function validatedBeacon(client: ChainClient, beacon: RandomnessBeacon): Promise<RandomnessBeacon> {
async function validatedBeacon(client: ChainClient, beacon: RandomnessBeacon, expectedRound: number): Promise<RandomnessBeacon> {
if (client.options.disableBeaconVerification) {
return beacon
}
const info = await client.chain().info()
if (!await verifyBeacon(info, beacon)) {
if (!await verifyBeacon(info, beacon, expectedRound)) {
throw Error('The beacon retrieved was not valid!')
}

Expand Down
30 changes: 18 additions & 12 deletions test/beacon-verification.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ describe('verifyBeacon', () => {
signature: '94da96b5b985a22a3d99fa3051a42feb4da9218763f6c836fca3770292dbf4b01f5d378859a113960548d167eaa144250a2c8e34c51c5270152ac2bc7a52632236f746545e0fae52f69068c017745204240d19dae2b4d038cef3c6047fcd6539'
}

expect(await verifyBeacon(chainInfo, beacon)).toBeTruthy()
expect(await verifyBeacon(chainInfo, beacon, beacon.round)).toBeTruthy()
})

it('should not validate unchained beacons that are invalid', async () => {
Expand All @@ -57,7 +57,7 @@ describe('verifyBeacon', () => {
signature: '94da96b5b985a22a3d99fa3051a42feb4da9218763f6c836fca3770292dbf4b01f5d378859a113960548d167eaa144250a2c8e34c51c5270152ac2bc7a52632236f746545e0fae52f69068c017745204240d19dae2b4d038cef3c6047fcd6539'
}

expect(await verifyBeacon(chainInfo, beacon)).toBeFalsy()
expect(await verifyBeacon(chainInfo, beacon, beacon.round)).toBeFalsy()
})

it('should validate chained beacon from the go codebase', async () => {
Expand All @@ -72,7 +72,7 @@ describe('verifyBeacon', () => {
previous_signature: 'a2237ee39a1a6569cb8e02c6e979c07efe1f30be0ac501436bd325015f1cd6129dc56fd60efcdf9158d74ebfa34bfcbd17803dbca6d2ae8bc3a968e4dc582f8710c69de80b2e649663fef5742d22fff7d1619b75d5f222e8c9b8840bc2044bce'
}

expect(await verifyBeacon(chainInfo, beacon)).toBeTruthy()
expect(await verifyBeacon(chainInfo, beacon, beacon.round)).toBeTruthy()
})

it('should not validate chained beacon without a previous_signature', async () => {
Expand All @@ -86,7 +86,7 @@ describe('verifyBeacon', () => {
signature: '88ccd9a91946bc0bbef2c6c60a09bbf4a247b1d2059522449aa1a35758feddfad85efe818bbde3e1e4ab0c852d96e65f0b1f97f239bf3fc918860ea846cbb500fcf7c9d0dd3d851320374460b5fc596b8cfd629f4c07c7507c259bf9beca850a',
}

expect(await verifyBeacon(chainInfo, beacon)).toBeFalsy()
expect(await verifyBeacon(chainInfo, beacon, beacon.round)).toBeFalsy()
})
it('should not validate an invalid chained beacon', async () => {
const chainInfo = createChainInfo(
Expand All @@ -101,7 +101,7 @@ describe('verifyBeacon', () => {
previous_signature: 'a2237ee39a1a6569cb8e02c6e979c07efe1f30be0ac501436bd325015f1cd6129dc56fd60efcdf9158d74ebfa34bfcbd17803dbca6d2ae8bc3a968e4dc582f8710c69de80b2e649663fef5742d22fff7d1619b75d5f222e8c9b8840bc2044bce'
}

expect(await verifyBeacon(chainInfo, beacon)).toBeFalsy()
expect(await verifyBeacon(chainInfo, beacon, beacon.round)).toBeFalsy()
})

it('should not validate an unchained beacon with a chained beacon scheme in ChainInfo ', async () => {
Expand All @@ -118,7 +118,7 @@ describe('verifyBeacon', () => {
signature: '94da96b5b985a22a3d99fa3051a42feb4da9218763f6c836fca3770292dbf4b01f5d378859a113960548d167eaa144250a2c8e34c51c5270152ac2bc7a52632236f746545e0fae52f69068c017745204240d19dae2b4d038cef3c6047fcd6539'
}

expect(await verifyBeacon(chainInfo, beacon)).toBeFalsy()
expect(await verifyBeacon(chainInfo, beacon, beacon.round)).toBeFalsy()
})
it('should not validate a chained beacon with an unchained beacon scheme in ChainInfo', async () => {
// unchained scheme
Expand All @@ -135,7 +135,7 @@ describe('verifyBeacon', () => {
previous_signature: 'a2237ee39a1a6569cb8e02c6e979c07efe1f30be0ac501436bd325015f1cd6129dc56fd60efcdf9158d74ebfa34bfcbd17803dbca6d2ae8bc3a968e4dc582f8710c69de80b2e649663fef5742d22fff7d1619b75d5f222e8c9b8840bc2044bce'
}

expect(await verifyBeacon(chainInfo, beacon)).toBeFalsy()
expect(await verifyBeacon(chainInfo, beacon, beacon.round)).toBeFalsy()
})

it('should not validate if the randomness isnt what was signed', async () => {
Expand All @@ -150,7 +150,7 @@ describe('verifyBeacon', () => {
signature: '94da96b5b985a22a3d99fa3051a42feb4da9218763f6c836fca3770292dbf4b01f5d378859a113960548d167eaa144250a2c8e34c51c5270152ac2bc7a52632236f746545e0fae52f69068c017745204240d19dae2b4d038cef3c6047fcd6539'
}

expect(await verifyBeacon(chainInfo, beacon)).toBeFalsy()
expect(await verifyBeacon(chainInfo, beacon, beacon.round)).toBeFalsy()
})
describe('signatures on G1', () => {
const validBeacon = {
Expand All @@ -169,12 +169,15 @@ describe('verifyBeacon', () => {
}

it('should verify a signature on G1', async () => {
await expect(verifyBeacon(chainInfo, validBeacon)).resolves.toEqual(true)
await expect(verifyBeacon(chainInfo, validBeacon, validBeacon.round)).resolves.toEqual(true)
})

it('should not verify a signature on G1 for the wrong round', async () => {
const invalidBeacon = {...validBeacon, round: 55}
await expect(verifyBeacon(chainInfo, invalidBeacon)).resolves.toEqual(false)
await expect(verifyBeacon(chainInfo, invalidBeacon, invalidBeacon.round)).resolves.toEqual(false)
})
it('should not verify a valid beacon with the wrong expected round', async () => {
await expect(verifyBeacon(chainInfo, validBeacon, 2)).resolves.toEqual(false)
})
})
describe('signatures on G1 with DST', () => {
Expand All @@ -195,11 +198,14 @@ describe('verifyBeacon', () => {
}

it('should verify a valid signature', async () => {
await expect(verifyBeacon(chainInfo, validBeacon)).resolves.toEqual(true)
await expect(verifyBeacon(chainInfo, validBeacon, validBeacon.round)).resolves.toEqual(true)
})
it('should not verify a signature on G1 for the wrong round', async () => {
const invalidBeacon = {...validBeacon, round: 55}
await expect(verifyBeacon(chainInfo, invalidBeacon)).resolves.toEqual(false)
await expect(verifyBeacon(chainInfo, invalidBeacon, invalidBeacon.round)).resolves.toEqual(false)
})
it('should not verify a valid beacon with the wrong expected round', async () => {
await expect(verifyBeacon(chainInfo, validBeacon, 2)).resolves.toEqual(false)
})
})
})

0 comments on commit c708e9d

Please sign in to comment.