-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #107 from ChainSafe/cayman/discv5.1
Initial discv5.1 update
- Loading branch information
Showing
28 changed files
with
1,397 additions
and
1,312 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,22 +1,31 @@ | ||
// length of a tag in a packet | ||
export const TAG_LENGTH = 32; | ||
export const MAX_PACKET_SIZE = 1280; | ||
export const MIN_PACKET_SIZE = 63; | ||
|
||
// length of an authentication tag | ||
export const AUTH_TAG_LENGTH = 12; | ||
export const MASKING_KEY_SIZE = 16; | ||
|
||
// length of magic token | ||
export const MAGIC_LENGTH = 32; | ||
export const PROTOCOL_SIZE = 6; | ||
export const VERSION_SIZE = 2; | ||
export const FLAG_SIZE = 1; | ||
export const NONCE_SIZE = 12; | ||
export const AUTHDATA_SIZE_SIZE = 2; | ||
export const STATIC_HEADER_SIZE = 23; | ||
|
||
// length of nonce | ||
export const ID_NONCE_LENGTH = 32; | ||
export const MESSAGE_AUTHDATA_SIZE = 32; | ||
export const WHOAREYOU_AUTHDATA_SIZE = 24; | ||
export const MIN_HANDSHAKE_AUTHDATA_SIZE = 34 + 64 + 33; | ||
|
||
export const RANDOM_DATA_LENGTH = 44; | ||
export const SIG_SIZE_SIZE = 1; | ||
export const EPH_KEY_SIZE_SIZE = 1; | ||
|
||
export const MAX_PACKET_SIZE = 1280; | ||
export const MASKING_IV_SIZE = 16; | ||
|
||
export const ID_NONCE_SIZE = 16; | ||
|
||
export const ERR_TOO_SMALL = "ERR_PACKET_TOO_SMALL"; | ||
export const ERR_TOO_LARGE = "ERR_PACKET_TOO_LARGE"; | ||
|
||
export const WHOAREYOU_STRING = "WHOAREYOU"; | ||
export const ERR_INVALID_PROTOCOL_ID = "ERR_INVALID_PROTOCOL_ID"; | ||
export const ERR_INVALID_VERSION = "ERR_INVALID_VERSION"; | ||
export const ERR_INVALID_FLAG = "ERR_INVALID_FLAG"; | ||
|
||
export const ERR_TOO_SMALL = "packet too small"; | ||
export const ERR_TOO_LARGE = "packet too large"; | ||
export const ERR_UNKNOWN_FORMAT = "unknown format"; | ||
export const ERR_INVALID_BYTE_SIZE = "invalid byte size"; | ||
export const ERR_INVALID_AUTHDATA_SIZE = "ERR_INVALID_AUTHDATA_SIZE"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,78 +1,41 @@ | ||
import { randomBytes } from "bcrypto/lib/random"; | ||
import sha256 = require("bcrypto/lib/sha256"); | ||
import { NodeId, SequenceNumber } from "../enr"; | ||
import { ID_NONCE_SIZE, MASKING_IV_SIZE, NONCE_SIZE } from "./constants"; | ||
import { encodeMessageAuthdata, encodeWhoAreYouAuthdata } from "./encode"; | ||
import { IHeader, IPacket, PacketType } from "./types"; | ||
|
||
import { AUTH_TAG_LENGTH, ID_NONCE_LENGTH, RANDOM_DATA_LENGTH, WHOAREYOU_STRING } from "./constants"; | ||
import { Tag, AuthTag, IWhoAreYouPacket, IAuthResponse, Nonce, IAuthHeader, PacketType, IRandomPacket } from "./types"; | ||
import { NodeId, SequenceNumber, ENR } from "../enr"; | ||
import { fromHex, toHex } from "../util"; | ||
|
||
export function createRandomPacket(tag: Tag): IRandomPacket { | ||
return { | ||
type: PacketType.Random, | ||
tag, | ||
authTag: randomBytes(AUTH_TAG_LENGTH), | ||
message: randomBytes(RANDOM_DATA_LENGTH), | ||
}; | ||
} | ||
|
||
export function createMagic(nodeId: NodeId): Buffer { | ||
return sha256.digest(Buffer.concat([fromHex(nodeId), Buffer.from(WHOAREYOU_STRING, "utf-8")])); | ||
} | ||
|
||
export function createWhoAreYouPacket(nodeId: NodeId, authTag: AuthTag, enrSeq: SequenceNumber): IWhoAreYouPacket { | ||
export function createHeader(flag: PacketType, authdata: Buffer, nonce = randomBytes(NONCE_SIZE)): IHeader { | ||
return { | ||
type: PacketType.WhoAreYou, | ||
magic: createMagic(nodeId), | ||
token: authTag, | ||
idNonce: randomBytes(ID_NONCE_LENGTH), | ||
enrSeq: Number(enrSeq), | ||
protocolId: "discv5", | ||
version: 1, | ||
flag, | ||
nonce, | ||
authdataSize: authdata.length, | ||
authdata, | ||
}; | ||
} | ||
|
||
export function createAuthTag(): AuthTag { | ||
return randomBytes(AUTH_TAG_LENGTH); | ||
} | ||
|
||
export function createAuthHeader( | ||
idNonce: Nonce, | ||
ephemeralPubkey: Buffer, | ||
authResponse: Buffer, | ||
authTag?: AuthTag | ||
): IAuthHeader { | ||
export function createRandomPacket(srcId: NodeId): IPacket { | ||
const authdata = encodeMessageAuthdata({ srcId }); | ||
const header = createHeader(PacketType.Message, authdata); | ||
const maskingIv = randomBytes(MASKING_IV_SIZE); | ||
const message = randomBytes(44); | ||
return { | ||
authTag: authTag || createAuthTag(), | ||
idNonce, | ||
authSchemeName: "gcm", | ||
ephemeralPubkey, | ||
authResponse, | ||
maskingIv, | ||
header, | ||
message, | ||
}; | ||
} | ||
|
||
export function createAuthResponse(signature: Buffer, enr?: ENR): IAuthResponse { | ||
export function createWhoAreYouPacket(nonce: Buffer, enrSeq: SequenceNumber): IPacket { | ||
const idNonce = randomBytes(ID_NONCE_SIZE); | ||
const authdata = encodeWhoAreYouAuthdata({ idNonce, enrSeq }); | ||
const header = createHeader(PacketType.WhoAreYou, authdata, nonce); | ||
const maskingIv = randomBytes(MASKING_IV_SIZE); | ||
const message = Buffer.alloc(0); | ||
return { | ||
version: 5, | ||
signature, | ||
nodeRecord: enr, | ||
maskingIv, | ||
header, | ||
message, | ||
}; | ||
} | ||
|
||
// calculate node id / tag | ||
|
||
export function createSrcId(dstId: NodeId, tag: Tag): NodeId { | ||
const hash = sha256.digest(fromHex(dstId)); | ||
// reuse `hash` buffer for output | ||
for (let i = 0; i < 32; i++) { | ||
hash[i] = hash[i] ^ tag[i]; | ||
} | ||
return toHex(hash); | ||
} | ||
|
||
export function createTag(srcId: NodeId, dstId: NodeId): Tag { | ||
const nodeId = fromHex(srcId); | ||
const hash = sha256.digest(fromHex(dstId)); | ||
// reuse `hash` buffer for output | ||
for (let i = 0; i < 32; i++) { | ||
hash[i] = hash[i] ^ nodeId[i]; | ||
} | ||
return hash; | ||
} |
Oops, something went wrong.