rlpx-ecies.js
1 const { randomBytes } = require('crypto') 2 const secp256k1 = require('secp256k1') 3 const test = require('tape') 4 const util = require('../src/util') 5 const ECIES = require('../src/rlpx/ecies') 6 7 const testdata = require('./testdata.json') 8 9 function randomBefore (fn) { 10 return (t) => { 11 const privateKey1 = util.genPrivateKey(32) 12 const privateKey2 = util.genPrivateKey(32) 13 const publicKey1 = secp256k1.publicKeyCreate(privateKey1, false) 14 const publicKey2 = secp256k1.publicKeyCreate(privateKey2, false) 15 t.context = { 16 a: new ECIES(privateKey1, util.pk2id(publicKey1), util.pk2id(publicKey2)), 17 b: new ECIES(privateKey2, util.pk2id(publicKey2), util.pk2id(publicKey1)) 18 } 19 20 fn(t) 21 } 22 } 23 24 function testdataBefore (fn) { 25 return (t) => { 26 const v = testdata.eip8Values 27 const keyA = Buffer.from(v.keyA, 'hex') 28 const keyB = Buffer.from(v.keyB, 'hex') 29 const pubA = Buffer.from(v.pubA, 'hex') 30 const pubB = Buffer.from(v.pubB, 'hex') 31 const h = testdata.eip8Handshakes 32 33 t.context = { 34 a: new ECIES(keyA, util.pk2id(pubA), util.pk2id(pubB)), 35 b: new ECIES(keyB, util.pk2id(pubB), util.pk2id(pubA)), 36 h0: { 37 'auth': Buffer.from(h[0].auth.join(''), 'hex'), 38 'ack': Buffer.from(h[0].ack.join(''), 'hex') 39 }, 40 h1: { 41 'auth': Buffer.from(h[1].auth.join(''), 'hex'), 42 'ack': Buffer.from(h[1].ack.join(''), 'hex') 43 } 44 } 45 fn(t) 46 } 47 } 48 49 test('Random: message encryption', randomBefore((t) => { 50 const message = Buffer.from('The Magic Words are Squeamish Ossifrage') 51 const encrypted = t.context.a._encryptMessage(message) 52 const decrypted = t.context.b._decryptMessage(encrypted) 53 t.same(message, decrypted, 'encryptMessage -> decryptMessage should lead to same') 54 t.end() 55 })) 56 57 test('Random: auth -> ack -> header -> body (old format/no EIP8)', randomBefore((t) => { 58 t.doesNotThrow(() => { 59 const auth = t.context.a.createAuthNonEIP8() 60 t.context.b._gotEIP8Auth = false 61 t.context.b.parseAuthPlain(auth) 62 }, 'should not throw on auth creation/parsing') 63 64 t.doesNotThrow(() => { 65 t.context.b._gotEIP8Ack = false 66 const ack = t.context.b.createAckOld() 67 t.context.a.parseAckPlain(ack) 68 }, 'should not throw on ack creation/parsing') 69 70 const body = randomBytes(600) 71 const header = t.context.b.parseHeader(t.context.a.createHeader(body.length)) 72 t.same(header, body.length, 'createHeader -> parseHeader should lead to same') 73 74 const parsedBody = t.context.b.parseBody(t.context.a.createBody(body)) 75 t.same(parsedBody, body, 'createBody -> parseBody should lead to same') 76 77 t.end() 78 })) 79 80 test('Random: auth -> ack (EIP8)', randomBefore((t) => { 81 t.doesNotThrow(() => { 82 const auth = t.context.a.createAuthEIP8() 83 t.context.b._gotEIP8Auth = true 84 t.context.b.parseAuthEIP8(auth) 85 }, 'should not throw on auth creation/parsing') 86 87 t.doesNotThrow(() => { 88 const ack = t.context.b.createAckEIP8() 89 t.context.a._gotEIP8Ack = true 90 t.context.a.parseAckEIP8(ack) 91 }, 'should not throw on ack creation/parsing') 92 93 t.end() 94 })) 95 96 test('Testdata: auth -> ack (old format/no EIP8)', testdataBefore((t) => { 97 t.doesNotThrow(() => { 98 t.context.b._gotEIP8Auth = false 99 t.context.b.parseAuthPlain(t.context.h0.auth) 100 t.context.a._initMsg = t.context.h0.auth 101 }, 'should not throw on auth parsing') 102 103 t.doesNotThrow(() => { 104 t.context.a._gotEIP8Ack = false 105 t.context.a.parseAckPlain(t.context.h0.ack) 106 }, 'should not throw on ack parsing') 107 108 t.end() 109 })) 110 111 test('Testdata: auth -> ack (EIP8)', testdataBefore((t) => { 112 t.doesNotThrow(() => { 113 t.context.b._gotEIP8Auth = true 114 t.context.b.parseAuthEIP8(t.context.h1.auth) 115 t.context.a._initMsg = t.context.h1.auth 116 }, 'should not throw on auth parsing') 117 t.doesNotThrow(() => { 118 t.context.a._gotEIP8Ack = true 119 t.context.a.parseAckEIP8(t.context.h1.ack) 120 }, 'should not throw on ack parsing') 121 122 t.end() 123 }))